[Algorithm Beaten Diary] day10——704. Binary search, 34. Find the first and last position of an element in a sorted array

 

 704. Binary search 

704. Binary search

Topic description: 

Given a  n sorted (ascending) integer array of elements  nums and a target value  target  , write a function that  nums returns  targetthe index if the target value exists, otherwise returns  -1

Problem-solving ideas: 

The array in this question is ordered and bi-segmented, so we can use the binary algorithm to solve this problem

It is worth noting that when left and right continue to move to the middle, left and right may point to the same position, and this position needs to be judged, so our loop condition is left<=right

 Solution code:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0;
        int right=nums.size()-1;
        while(left<=right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]==target) return mid;
            if(nums[mid]>target) right=mid-1;
            if(nums[mid]<target) left=mid+1;
        }
        return -1;
        }
};

 34. Find first and last position of element in sorted array

34. Find first and last position of element in sorted array

 Topic description:

You are given an array of integers in non-decreasing order  nums, and a target value  target. Please find the starting position and ending position of the given target value in the array.

targetReturns  if the target value does not exist in the array  [-1, -1].

O(log n) You must design and implement an algorithm with time complexity of  .

Problem-solving ideas:

In this question, we use bisection to solve the problem of left and right endpoints. First of all, there must be left and right.

Let’s understand this question through an example: [1,2,3,3,3,4,5]

Find the left endpoint : Here we use t instead of target (this is easier to describe)

  • Binary thinking operation: We can divide the above example into two parts, because we are now looking for the left endpoint, so I can divide the example into [[1,2 ] , [3,3,3,4,5] ]

  1. When x<t, it is in the interval [1,2], left=mid+1
  2. When x>=t, it is in the interval [3,3,3,4,5], right=mid (it cannot be equal to mid-1 here, because if mid=0, right=-1 will go out of bounds)
  • Details:

Loop condition:

  1. left<right     
  2. left<=right   ×

Which one do we choose? Let’s discuss:

  1. There are results
  2. All are greater than t (t1), right keeps going to the left, and finally right ends with left. If left<=right, there will be an infinite loop.
  3. All are less than t (t2), left keeps going to the right, and finally left ends on the right of right

From this we can only choose the first option but not the second option!

Find the intermediate operation:

  1. left+(right-left)/2        ×
  2. left+(right-left+1)/2    

Let’s find out by considering the extreme cases! When there are only two elements left:

There is no problem with the first type, but mid=0+2/2=1 with the second type. When the left+1 operation is performed, an out-of-bounds event will occur.

Find the right endpoint :

  • Binary thinking operation: We can divide the above example into two parts, because we are now looking for the left endpoint, so I can divide the example into [ [1,2,3,3,3 ] .[4,5] ]

  1. When x<=t, it is in the interval [1,2,3,3,3], left=mid
  2. When x>t, it is in the interval [4,5], right=mid-1
  • Details:

Loop condition:

  1. left<right     
  2. left<=right   ×

Or choose left<right

Find the intermediate operation:

  1. left+(right-left)/2        
  2. left+(right-left+1)/2    ×

Let’s find out by considering the extreme cases! When there are only two elements left:

In the first case, when mid=0+1/2=0, right=mid-1 is out of bounds. In the second case, there is no problem.

Solution code:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        //特殊情况处理一下
        if(nums.size()==0)return {-1,-1};
        int left=0,right=nums.size()-1;
        vector<int> ret;
        //查找左端点
        while(left<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]<target)left=mid+1;
            if(nums[mid]>=target)right=mid;
        }
        //当left==right时就是结果
        if(nums[left]!=target)return {-1,-1};
        else ret.push_back(left);
        //查找右端点
        left=0,right=nums.size()-1;
        while(left<right)
        {
            int mid=left+(right-left+1)/2;
            if(nums[mid]<=target)left=mid;
            if(nums[mid]>target)right=mid-1;
        }
        if(nums[right]!=target)return {-1,-1};
        else ret.push_back(right);
        return ret;
    }
};

 

Guess you like

Origin blog.csdn.net/m0_69061857/article/details/133323980