leetcode hot 100二分查找

leetcode hot 100二分查找_第1张图片
本题是二分查找,在二分查找的过程中,存在两个问题点
第一点是在while循环的时候,是判断left 第二点是当移动left和right的时候,是应该令其为mid,还是mid+1/mid-1?

这两个问题,都是因为区间划分所产生的,平常区间划分采用左闭右闭或者左闭右开。

那么,我们先以左闭右闭为例子,
如果left<=right,这个区间是不是一个合法区间?比如[1,1],这个区间表示左边是1,右边也是1,并且两边都包括,那么,这个区间上就有1这个数字,所以是合法的。
如果nums[mid]target,说明,目标值在左边,这个时候我们需要更新右边界,这个时候,因为我们也已经比较过nums[mid]了,所以我们直接令right=mid-1。

class Solution {
    public int search(int[] nums, int target) {
        // 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
        if (target < nums[0] || target > nums[nums.length - 1]) {
            return -1;
        }
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid - 1;
        }
        return -1;
    }
}

然后我们分析左闭右开的情况,这个时候,我们的区间是[1,1),这显然是不合法的,所以我们就不能让lef<=right了,只能lefttarget,那么说明target在左边,移动右边界,但由于区间是右开的,上一次循环并没有包括有边界,所以我们让right= mid即可。同时我们应该注意,左闭右开的情况就不需要判断target是否小于区间最小值或者大于区间最大值了,然后,left=0,right应该等于nums[].length,而不是nums[].length-1,这样才能比较所有的元素。

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = left + ((right - left) >> 1);
            if (nums[mid] == target)
                return mid;
            else if (nums[mid] < target)
                left = mid + 1;
            else if (nums[mid] > target)
                right = mid;
        }
        return -1;
    }
}

你可能感兴趣的:(leetcode,算法,数据结构)