二分探索と二分境界処理

二分探索とは

一般的に、二分探索とは、ソートされた配列で回答の範囲を見つけ、そのたびに範囲の中間値を取得することです。この値が大きい場合は、前半を取り、範囲を狭め続けます。値が小さい場合は、後半を取り、範囲を狭めます。
毎回1/2の範囲を狭めることができ、徐々に答えが得られます。

サンプル誤差境界

質問の例:https//www.acwing.com/problem/content/description/1229/
この質問は明らかに2つのポイントに分けることができます。列挙が
1〜100000の場合、l = 1、r = 1e5、mid =を設定します。 (l + r)/ 2;
以前は、midが小さい場合はl = mid + 1を使用し、midが大きい場合はr = mid-1を使用していましたが、この質問の答えが5の場合、答えは間違っています。 。 なぜ?
図に示すように、各行の最初の行はl、2番目の行はr、3番目の
ここに画像の説明を挿入
質問はmidです。この質問の答えが5の場合、mid = 4の場合、l = mid + 1、つまりlです。 = 5、ループを終了します。最終的な答えは4です。

境界

(1)mid=(l+r)/2実際には、(l + r)/ 2は切り捨てられます。l = mid、r = mid + 1の場合、l + 1がループを直接終了し、r = mid +1の値が取得されていない場合。
切り捨てられるため、つまりl <= mid < r、midは常にrの値よりも小さくなり、midが大きい場合はr = midに変更できます。

    while(l<r){
    
    
        int mid = (l+r)/2;
       判断成立语句;

        if(满足条件){
    
    
            ans=mid;
            l=mid+1;
        }
        else{
    
    
            r=mid;
        }
    }

(2)切り上げることもできmid=(l+r+1)/2ます。同様に、l < mid <= rmidがlと等しくなることはありません。この時点で、midに変更できます。midが小さい場合は、l = midであり、コードが使用可能です。

    while(l<r){
    
    
        int mid = (l+r+1)/2;
       判断成立语句;

        if(满足条件){
    
    
            ans=mid;
            l=mid;
        }
        else{
    
    
            r=mid-1;
        }
    }

おすすめ

転載: blog.csdn.net/qq_45758578/article/details/113209836