美文网首页
leetcode704-二分查找

leetcode704-二分查找

作者: 巡山的小猴子 | 来源:发表于2024-02-18 15:58 被阅读0次

这个题思路很简单,而且酒桌上也总玩,也想出坑害别人的办法(就剩下两个数字给下家,那么就是最后两个人喝酒了)哈哈哈
但是真正做这个题,边界很不好考虑

class Solution {
    public int search(int[] nums, int target) {
        int left = 0;
        int right = nums.length -1;
        while(left <= right){
            int mid = left + ((right - left) / 2);
            if (target > nums[mid]){
                left = mid +1;
            }else if(target < nums[mid]){
                right = mid - 1;
            }
            if(target == nums[mid]){
                return mid;
            }
        }
        return -1;
    }
}
  1. while(left <= right) 循环这么写,写上等号,因为要考虑mid 等于left,或者right的情况,没有等号可能导致找不到
  2. left + ((right - left) / 2) 替代(right + left) / 2 防止数组太大了,int 溢出了
  3. left = mid +1,right = mid - 1 这个主动缩小范围的+1,-1 不能省略,原来觉得不就是扩大了范围,多迭代一两次么。其实是,如果不缩小范围,就会导致死循环,特别是当mid恰好等于left或right时,这种调整方式不会改变搜索范围,因为在下一次迭代中mid将会再次计算为相同的值,从而导致循环不会停止。

举例说明:

用例是nums2 = {-1, 0, 3, 5, 9, 12},目标值target2 = 2。

初始条件:

left = 0
right = 5 (因为数组长度为6)
第一次迭代:

mid = 0 + (5 - 0) / 2 = 2(使用整数除法,结果向下取整)
nums2[mid] = 3
由于3 > 2,按照新的调整方式,right = mid = 2
第二次迭代:

left = 0
right = 2
mid = 0 + (2 - 0) / 2 = 1
nums2[mid] = 0
由于0 < 2,按照新的调整方式,left = mid = 1
第三次迭代:

left = 1
right = 2
mid = 1 + (2 - 1) / 2 = 1(因为使用整数除法,结果向下取整)
nums2[mid] = 0
由于0 < 2,按照新的调整方式,left = mid = 1
可以看出,从第三次迭代开始,left、mid、right的值不再发生变化,因为left和mid都被重复设置为1,而right保持在2。这导致算法陷入了死循环,因为它不再能够递进地缩小搜索范围。

这个例子展示了为什么使用left = mid;和right = mid;这种调整方式可能会导致算法无法正确前进,特别是在目标值不存在于数组中时。正确的做法应该是在目标值大于mid值时让left等于mid + 1,在目标值小于mid值时让right等于mid - 1,这样可以保证每一次迭代都能有效缩小搜索范围,最终避免死循环。

相关文章

网友评论

      本文标题:leetcode704-二分查找

      本文链接:https://www.haomeiwen.com/subject/dwhmadtx.html