二分探索の簡単な実装

二分探索の実装を単純に記録する

記事ディレクトリ

序文

1.二分探索とは何ですか?

2. コードの実装

要約する


序文

この日、Liuhua さんは面接のために会社に来ましたが、面接官は「順序付けられた整数配列と値を与えれば、添字を返す簡単なクエリを作成できます。」これを聞いたとき、あなたは頭の後ろまで笑いました。キーボードを取り出し、for ループを入力してクエリを走査します。それを見た面接官はうなずき、真剣にこう言った、「若者、骨は大丈夫ですね。帰って知らせを待ってください。あなたには大きなチャンスがあると思いますよ!」 それを聞いたあなたは興奮して家に帰り、「ただの面接だけど、それだけ…」と思いながら知らせを待ちました、それからは何のフォローもありませんでした。

1.二分探索とは何ですか?

値を指定して、[1, 2, 3, 4, 5, 6, 7, 8] などの順序付き整数配列をクエリするには、5 に対応する位置 (添え字) を見つける必要があります配列の真ん中の数字(ここでは4)を選択し、検索対象の値と比較し、等しい場合はそのまま答え(添え字)を返します。そうでない場合は、次の 2 つのケースを考慮する必要があります。

1) 中央の数値が目標値より大きい場合、中央の数値右側にあるすべての数値が目標値より大きく、すべて除外されます。

2) 中央の数値が目標値より小さい場合、中央の数値左側にあるすべての数値が目標値より小さく、すべて除外されます。

それからこのように続きます。

注: ここでは、順序付けされた整数配列であることを何度も強調してきましたが、結局のところ、順序付けされていない場合、中央の数値の反対側の数値がターゲットの数値より完全に大きい (小さい) かどうかを判断できず、除外されます次に、クエリのターゲット値は 1 つだけであり、複数にすることはできません。

2. コードの実装

二分探索の開始と終了が異なり、それに対応する反復方法も異なり、次の 2 つの方法があります。

  • 左を閉じて右を閉じる[left, right]

  • 左閉 右開 [左、右)

 左閉じコードと右閉じコードは次のとおりです。

    private static int binarySearch(int target, int[] arry) {
        int left = 0, right = arry.length - 1;
        while (left <= right){
            int mid = (left + right) >>> 1;
            if (arry[mid] == target){
                return mid;
            } else if (arry[mid] < target) {
                left = mid + 1;
            } else if (arry[mid] > target) {
                right = mid - 1;
            }
        }
        return -1;
    }

左閉じと右開きの違いは、配列の右境界が配列の長さを選択するのに対し、左閉じと右閉じの境界は配列の長さ -1 を選択することです。ループ条件の判定もあります。詳しくは、【二分探索】詳細図_Charon_ccのブログ - CSDNブログをご覧ください。

コードは以下のように表示されます。

    private static int binarySearch(int target, int arry[])
    {
        int left = 0;
        int right = arry.length; //定义target在左闭右开的区间里,即[left, right)
        while (left < right) {	//因为left = right的时候,在[left, right)区间上无意义
            int middle = (left + right) >>> 1;
            if (arry[middle] > target) {
                right = middle; //target 在左区间,在[left, middle)中 
            } else if (arry[middle] < target) {
                left = middle + 1;
            } else {
                return middle;
            }
        }
        // 没找到就返回-1
        return -1;
    }

テスト:

n 個の要素とターゲット値 target を持つ順序付き (昇順) 整数配列 nums を指定すると、nums でターゲットを検索し、ターゲット値が存在する場合は添字を返し、存在しない場合は -1 を返す関数を作成します。

例 1:

入力: nums = [-1,0,3,5,9,12]、ターゲット = 9
出力: 4
説明: 9 は添え字 4 とともに nums に表示されます。

結果:

例 2:

入力: nums = [-1,0,3,5,9,12]、ターゲット = 2
出力: -1
説明: nums に 2 が存在しないため、-1 を返します。

結果:


要約する

二分探索の 2 つの最も重要な点は、ループ条件とその後の区間割り当て問題です。

両者は相互に関連しており、影響し合っているため、統一する必要があり、統一していないと問題が生じます。

したがって、ループ条件と代入問題は統一される、つまりループ不変である必要があります。

おすすめ

転載: blog.csdn.net/weixin_58403235/article/details/129843775