牛客题解每日一题【二分查找II】

牛客题解每日一题【二分查找II】_第1张图片
这道题唯一的考点就是如果当数组中存在重复的值,不修改边界的话可能会对结果值有一定的影响

如果不考虑数组中会存在重复的值,通常情况下会是这么写的

class Solution {
public:
    
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size();
        while(left < right)
        {
            
            int mid = (left + right) >> 1;
            //小于目标值排除左侧不可能重新确定左右区间
            if(nums[mid] < target)
            {
                left = mid + 1;
            }
            //大于目标值则肯定不再最右侧
            else if(nums[mid] > target)
            {
                right = mid - 1;
            }
            //找到了
            else
            {
               return mid;
            }
        }
      
        return -1;
    }
};

通过测试用例进一步分析
牛客题解每日一题【二分查找II】_第2张图片
步骤:
牛客题解每日一题【二分查找II】_第3张图片
通过我们的返回值也可以看到实际上返回的值是目标值的后一个值,因为存在重复值的问题,可能会导致程序在某些场景下误判了

修正思路:

牛客题解每日一题【二分查找II】_第4张图片

链接: link.

class Solution {
public:
   /**
    * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
    *
    * 如果目标值存在返回下标,否则返回 -1
    * @param nums int整型vector 
    * @param target int整型 
    * @return int整型
    */
   int search(vector<int>& nums, int target) {
       int left = 0;
       int right = nums.size() - 1;
       while(left < right)
       {
           
           int mid = (left + right) >> 1;
           //小于目标值排除左侧不可能,重新确定左区间
           if(nums[mid] < target)
           {
               left = mid + 1;
           }
           //大于目标值则肯定不再最右侧,重新确定右区间
           else if(nums[mid] > target)
           {
               right = mid - 1;
           }
           //第一次算出的来的位置既不大于也不小于,极大的可能会是目标值,那么右侧就可以完全排除
           //接下来可以在【0,mid) 这个区间里面查找
           else
           {
               right = mid;
           }
       }
       //防止数组越界,如果相遇的时候等于target就返回该位置的值
       if(nums.size() && nums[left] == target)
       {
           return left;
       }
       return -1;
   }
};

你可能感兴趣的:(牛客解题,算法,leetcode,排序算法)