Binary search for duplicates Find the leftmost or rightmost position subscript

Two points to find the far left

核心思想: 先mid =(l+r)/2每次向左取整; 然后命中target的时候,右边界逼近到mid;

Because mid is rounded to the left every time , when mid hits target, l replaces the position of mid , then the loop iteration will finally get stuck at the leftmost position of the repeated number!

You can use the extreme use case of int arr[5] = 3 3 3 3 3 ; int target = 3; to easily understand the above binary algorithm!

 //二分找k的最左侧位置
        while(l<r)
        {
    
    
            mid =  (l+r)>>1; //mid向左取整
            if(arr[mid]>=target ) r = mid;//mid命中时右边界r代替mid位置(二分区间整体向左收缩了)
            else l = mid+1;
        }

The search process diagram is as follows:

37_1


Two points to find the far right

核心思想: 先mid =(l+r+1)/2 每次向右取整; 然后命中target的时候,左边界逼近到mid;

Because mid is rounded to the right every time , when mid hits target, l replaces the position of mid , then the loop iteration will finally get stuck at the rightmost position of the repeated number! Same as above, but no more explanation;

 //二分找target的最右侧位置
        while(l<r)
        {
    
    
            mid =  (l+r+1)>>1; //mid向右取整
            if(arr[mid]<=target ) l = mid;//mid命中时左边界l代替mid位置(二分区间整体向右收缩了)
            else r = mid-1;
        }

Even if I don’t understand, I understand this thing five or six times. In fact, it contains some mathematical principles of boundaries, and memory can be understood from a macro perspective. After all, there are many boundary problems in the deformation of the bisection algorithm!


Comprehensive application (sword refers to offer)

Number of times a number occurs in an ascending array

insert image description here

This question requires O(logN) time complexity, so it must be two points! And ordered arrays...isn't this a natural dichotomous ordered condition;

topic analysis

  • It is observed that the positions where repeated numbers appear in the ordered array must be next to each other:

  • Then we only need to find the leftmost subscript il of the target value k, and its rightmost subscript ir, return ir-il+1; that's it! (Of course, you need to consider the case that k does not exist in the array, this is a small problem)

How to find the subscripts of the leftmost and rightmost k, that is the two dichotomous strategies designed above, need to master, commonly used!

Implementation code

class Solution {
    
    
public:
    int GetNumberOfK(vector<int> data ,int k) {
    
    
        //二分找重复的最左 和 最右
        if(data.size()==0) return 0;
        int r = data.size() - 1;
        int l = 0;
        int mid;
        int il;
        int ir;
        //二分找k的最左侧位置
        while(l<r)
        {
    
    
            mid =  (l+r)>>1; //向左取整
            if(data[mid]>=k) r = mid;//命中时右边界也向左逼近
            else l = mid+1;
        }
        if(data[l]!=k) return 0;//特殊情况,k不存在,返回0;
        il = l;
        

       //二分找k的最右侧位置
        l = 0;
        r = data.size() - 1;
         while(l<r)
        {
    
    
            mid =  (l+r+1)>>1;//向右取整
            if(data[mid]<=k) l = mid;//命中时左边界也向右逼近
            else r = mid-1;
        }
        ir = l;

        return ir-il+1;
    }
};

Supongo que te gusta

Origin blog.csdn.net/wtl666_6/article/details/129259790
Recomendado
Clasificación