いくつかの時間前、私が見フォーラムでの統計は、プログラマの90%が、単純な二分法に書き込むことができないと言います。二分法は非常に簡単で、右ではないでしょうか?そのセンセーショナルではないですか?
実際には、二分法は本当に、二分法の特に様々なバリエーションそれほど単純ではありません。最も単純な二分法は、見た目のソートされた配列からキーの値です。以下の手順。
/**
* 二分查找,找到该值在数组中的下标,否则为-1
*/
static int binarySerach(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] == key) { return mid; } else if (array[mid] < key) { left = mid + 1; } else { right = mid - 1; } } return -1; }
このプログラムは、私がいる限り有資格プログラマーとして記述することができるはずと信じています。各ポインタが移動し、左と右のことを少しノート、必要なときに無限ループを防ぐために、ミッド+1または-1、に基づいて、プログラムが正しく実行することができるようになります。
条件を少し変更した場合しかし、あなたはそれを書くのだろうか?例えば、データは、アレイ内の最小(または最大)のインデックスを一致戻すために必要なデータを繰り返してもよい。一歩近づく配列の最初の要素はキーより大きい見つける必要に(キーが最小値よりも大きいです)標準の要素の下に、というように。これらは、しかし、ときだけ少しの変化、彼らは本当にもっと慎重に達成したいです。以下に示すこれらのバイナリ検索バリアントを達成することです。
図1に示すように、第1均等の主要な要素を見つけます
// 查找第一个相等的元素
static int findFirstEqual(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] >= key) { right = mid - 1; } else { left = mid + 1; } } if (left < array.length && array[left] == key) { return left; } return -1; }
2、同等の重要な要素の最後を見つけます
// 查找最后一个相等的元素
static int findLastEqual(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] <= key) { left = mid + 1; } else { right = mid - 1; } } if (right >= 0 && array[right] == key) { return right; } return -1; }
図3は、最初の要素は、キー以上で発見します
// 查找第一个等于或者大于key的元素
static int findFirstEqualLarger(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] >= key) { right = mid - 1; } else { left = mid + 1; } } return left; }
4.キーよりも第1の要素が大きい検索
// 查找第一个大于key的元素
static int findFirstLarger(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] > key) { right = mid - 1; } else { left = mid + 1; } } return left; }
5、最後の重要な要素を見つけるために等しいか未満であります
// 查找最后一个等于或者小于key的元素
static int findLastEqualSmaller(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] > key) { right = mid - 1; } else { left = mid + 1; } } return right; }
6、最後の要素を見つけることが鍵に満ちません
// 查找最后一个小于key的元素
static int findLastSmaller(int[] array, int key) { int left = 0; int right = array.length - 1; // 这里必须是 <= while (left <= right) { int mid = (left + right) / 2; if (array[mid] >= key) { right = mid - 1; } else { left = mid + 1; } } return right; }
次に、我々は適切なテストアルゴリズムのこれら四つの変種行うことができます。
あなたが再び取り出さバイナリ検索を使用する際に、多くの時間は、ローカルアプリケーションバイナリサーチは、直接の発見と等しく重要な要素ではありませんが、上記のバイナリサーチの様々な変異体の使用は、これらの変異体をマスターそれも、より便利に感じるでしょう。
読者の福祉
上記の記事で、私は顔のインタビューの質問と回答のほとんどに関与インターネット企業のJavaプログラマを総括するために、誰もがダボ、Redisの、ネッティー、飼育係、春の雲を含む(ビデオ素材を共有するためのドキュメントアーキテクチャと自由を作りましたあなたの前のインタビューをレビューし、良い仕事を見つけるのに役立つことを期待して、だけでなく、あなたの情報をオンライン学習を検索するための時間を節約し、)分散、並行性の高いアーキテクチャの技術情報。
入手:qunグループを追加します:956 011 797 をクリックして今すぐ登録 妹を管理するための自由なアクセスを見つけるために!
合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!