0
点赞
收藏
分享

微信扫一扫

【leetcode】704.二分查找

杨沐涵 2022-03-13 阅读 62

1、题目

2、错误分析

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

上述为首次代码,显示通过,但是内存消耗高!

(1)变量n没有必要,直接调用size()-1赋值给right就可以;

(2)上述代码运行没有问题,即使当时并没有意识到开闭区间的问题,按照right=n-1,应该是[]闭区间,但是left<right判断条件就是在[)区间中寻找,因为mid(int相除,会丢弃小数位)会等left会取到左边,取不到右边,但是因为多问了一下,target此时是否还等于nums[mid],此时left被+1到了原本right的位置,就刚好补上了取不到right的隐藏bug.....解题思路并不清晰。。。

3、题解

(1)二分查找前提条件必须满足:排好序的+无重复元素;

(2)int/int,结果会丢弃小数位;

(3)正确认识一下,纠结的判断条件,当left<right,此时判断的区间是【left,right)左闭右开区间,是取不到right的值,因此开始right赋值就应该是nums.size(),没有-1(因为取不到),而在判断之后的right=mid;不需要-1,因为取不到;当left<=right,判断区间就是【left,right】,此时right=nums.size()-1,判断之后,right=mid-1;

(4)修正答案如下:(左闭右闭区间)

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)/2;//避免right+left造成大数
            int mid=left+(right-left)/2;//防止内存溢出(超出整数范围)
            //int mid=left+((right-left)>>1);//右移等于除以2
            if(target>nums[mid]){
                left=mid+1;
            }
            else if(target<nums[mid]){
                right=mid-1;
            }
            else
                return mid;
        }
        return -1;
  }
};

以下代码摘自“代码随想录”题解(左闭右开区间):

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
        while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
            int middle = left + ((right - left) >> 1);
            if (nums[middle] > target) {
                right = middle; // target 在左区间,在[left, middle)中
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,在[middle + 1, right)中
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};
举报

相关推荐

0 条评论