問題の説明:
秩序配列は、数与えられ、リターン添字を存在さ-1は存在しません。
。22人の再帰比較の種類:
最初に考えなければならない。この問題は、再帰的な実装です。
再帰Iの二種類のセグメントのアレイを達成することで、実際にここで言及-一方はに分割されて開閉する左右の形態、他方はであり、双方が閉じている形態。
・右オープン左が閉じ
int BinarySearch(vector<int> &nums, int l, int r, int target) {
// 不是你想象地那么完美
if (l == r) return -1;
int m = l + (r - l) / 2; // 防止溢出
// 建议还是把这个判断放在最前面
if (target == nums[m]) return m;
else if (target > nums[m]) return BinarySearch(nums, m + 1, r, target);
else if (target < nums[m]) return BinarySearch(nums, l, m, target);
}
- 長所:判断が終了し、特に都合の良い時間に、二つのポインタと会った、以上です。
- 短所:私たちは、[a、b)は間隔が[、c)は、[Cに完全に生きることができると、実際には右の開閉を残し 、b)の二つの部分。しかし、ここと役に立たない-私がする必要があるため、中央要素掘る非常に耳障りに見えます。
・すべての周りをクローズ
int BinarySearch(vector<int> &a, int l, int r, int target) {
if (l > r) return -1;
int m = l + (r - l) / 2; // 防止溢出
if (target == a[m]) return m;
else if (target > a[m]) return BS(a, m + 1, r, target);
else if (target < a[m]) return BS(a, l, m - 1, target);
}
私は、このようなアプローチは全く不利ではないことが判明し、前に考えてみたいです。M + 1、M - 1は、完全に中間処理エレメントDIGを反映しています。
除きノートにL == rは、処理しなければならないかもしれないときということです。
III。非再帰
単にとんでもない再帰的。だから我々は疑問に思ったかどうかを非再帰的な実装。
私たちは、スタックを導入する必要はありませんので、その後、我々は、末尾再帰を参照してください。限り循環対応するものとして。
あなたが私をここに使用する前に、実装は非常に単純である、と考える近い右近い何ら欠陥が残っていない達成します。
int BinarySearch(vector<int> &a, int target) {
// 左闭右也闭的形式
int l = 0;
int r = a.size() - 1;
while (l <= r) {
int m = l + (r - l) / 2; // 防止溢出
if (target == a[m]) return m;
else if (target > a[m]) l = m + 1;
else if (target < a[m]) r = m - 1;
}
return -1;
}
IV。その他の経験
- なお、要素の中央を掘るします。
- / - L +(L R)を使用して 2 加算器のオーバーフローを防止します。