【にポインタほう】

二ポインタ法 とは?

最終更新:
💡 2つの位置を動かし、候補を正しく絞る

配列などの2つの位置を管理し、条件に応じて進める探索の技法。位置を戻さず各更新が定数時間なら走査をO(n)にできますが、ソートの前処理や外側の繰り返しを含む全体の計算量は別に評価します。

📌 このページのポイント
二ポインタ法:和に応じて位置を動かす昇順の配列で、合計10のペアを探す①1L35711R1 + 11 = 12:大きいのでRを左へ②1L357R111 + 7 = 8:小さいのでLを右へ③13L57R113 + 7 = 10:異なる2要素を発見走査はO(n)。事前ソートの費用は別
青は左の位置L、橙は右の位置Rです。昇順なので不要な候補を除けます。配列の順序を保ち、和の大小に応じて片方の位置だけを動かします。
ひよこ ひよこ
二ポインタ法は何をする?
ペンギン先生 ペンギン先生
配列などの中で2つの位置を管理し、条件に応じて動かす方法だよ。たとえば昇順の配列で合計10の2要素を探すなら、最初は左右の端を選ぶ。和が大きければ右を左へ、小さければ左を右へ動かすんだ。同じ要素を2回使わないよう、左の位置が右より手前の間だけ調べるよ。
ひよこ ひよこ
候補を飛ばしても大丈夫?
ペンギン先生 ペンギン先生
昇順という条件が理由になるよ。左の値と右の値の和が10より大きければ、その右の値を残して左だけ増やしても和は小さくならない。だから右を小さい側へ動かせる。和が小さい場合は逆に左を増やす。条件に基づいて不要な候補を除くんだ。
ひよこ ひよこ
いつでもO(n)になる?
ペンギン先生 ペンギン先生
違うよ。位置を後戻りさせず、各更新が定数時間なら走査全体はO(n)と評価できる。未ソートの配列を比較ソートしてから2SUMを探すなら、通常は前処理を含めO(n log n)。3SUMで1要素を順に固定して残りを二ポインタで探す構成はO(n²)だよ。
ひよこ ひよこ
同じ方向に動かす方法もある?
ペンギン先生 ペンギン先生
あるよ。読み取り位置と書き込み位置で重複を除いたり、区間の左右の端を動かしたりする方法だね。ただし合計に基づいて区間を縮める場合、負の値があると和が単調に変わらず、正の値だけのときと同じ規則をそのまま使えないことがあるんだ。
ひよこ ひよこ
実装で何を確認する?
ペンギン先生 ペンギン先生
昇順などの前提、位置の範囲、終了条件、重複や同じ要素の扱いを確認する。動かすたびに何が保たれ、捨てた候補からは答えが出ないのかを説明しよう。二重ループに見えても位置の総移動回数で評価できる場合があり、見た目のループ数だけでは決めないんだ。
もっと詳しく知りたい人へ

区間の和を計算し直してもO(n)?

各移動のたびに区間全体を足し直せば、1回の更新が定数時間ではなくなります。適用条件が合う場合は、右端の値を加え、左端の値を引くなどの更新で和を保つことが重要です。位置の移動回数と、1回の更新費用を両方評価してください。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「二ポインタ法」って出てきたら「2つの位置で探索を進める技法」と思えばだいたいOK!
📖 おまけ:英語の意味
「Two Pointers Method」 = 2つの位置・ポインタを使う方法
💬 配列の添字や反復子など、今見ている場所を2つ管理します。両端からの探索だけでなく、同じ方向へ進む方法も含めて説明されます。

参考資料

← 用語集にもどる