二分探索パターン
カテゴリ: binary-search
概要
二分探索は、ソート済みの配列から特定の要素を効率的に検索するアルゴリズムです。各ステップで探索範囲を半分に絞り込むことで、線形探索(O(n))よりもはるかに高速に(O(log n))目的の要素を見つけることができます。「分割統治法」の一種で、問題を小さな部分問題に分割して解決するアプローチです。
コードテンプレート
int binarySearch(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // オーバーフロー防止
if (nums[mid] == target) {
return mid; // 要素が見つかった
} else if (nums[mid] < target) {
left = mid + 1; // 右半分を探索
} else {
right = mid - 1; // 左半分を探索
}
}
return -1; // 要素が見つからなかった
}
ひらめきのサポート
問題文に以下のようなキーワードや特徴がある場合、このパターンの適用を検討してみましょう。
チャート式ひらめきポイント
問題を読んだときに、「ソート済み配列で何かを見つける」「二つの要素の関係を調べる」「効率的に配列を操作する」などの特徴があれば、 双指針パターンが適用できる可能性が高いです。特に、O(n²)の計算量を避けたい場合に有効です。
このパターンを使用する問題例
- 1
二分探索(Binary Search): ソート済み配列から特定の値を検索する
- 2
最初と最後の位置を検索(Find First and Last Position): ソート済み配列で特定の値が最初と最後に現れる位置を見つける
- 3
回転されたソート配列での検索(Search in Rotated Sorted Array): 回転されたソート配列から特定の値を検索する
- 4
平方根の計算(Sqrt(x)): 整数の平方根を計算する(小数点以下切り捨て)
このパターンを使う問題
このパターンを適用して解くことができる実際の問題です。
回転ソート配列での検索
昇順でソートされた整数の配列が、ある位置で回転されています(例えば、[0,1,2,4,5,6,7] が [4,5,6,7,0,1,2] になるなど)。 与えられた配列 nums と目標値 targe...
ピーク要素を見つける
整数の配列 nums が与えられます。ピーク要素とは、その隣接する要素よりも大きい要素のことです。配列の最初と最後の要素は隣接要素がないため、それぞれ -∞ と比較されます。 ピーク要素のインデック...
ソート配列での要素の最初と最後の位置
整数の昇順にソートされた配列 `nums` と整数 `target` が与えられたとき、`target` が配列内で最初に現れる位置と最後に現れる位置を見つけてください。 `target` が配列内...
挿入位置の検索
昇順にソートされた整数の配列 `nums` と `target` 値が与えられたとき、`target` が見つかればそのインデックスを返します。見つからない場合は、`target` が挿入されるべき位...
ソート行列のK番目に小さい要素
n × n の行列が与えられ、各行と各列は昇順にソートされています。この行列の中でk番目に小さい要素を見つけてください。 k番目に小さい要素とは、行列を平坦化して昇順にソートした場合に、k番目(1-...
2つのソート配列の中央値
2つのソート済み配列 `nums1` と `nums2` が与えられたとき、2つの配列をマージした結果の中央値を求めてください。 全体の実行時間の複雑度は O(log(m+n)) である必要がありま...