二分查找思想+力扣实例

使用二分查找的场景:

1. 数组是一个有序数组(一般的题目为升序或者非递减数组);

2. 题目一般会强调数组中无重复元素,因为一旦有重复元素,使用二分查找返回的元素下标可能是不唯一的;

3. 如果一道题涉及在数组中查找某个目标元素(target)的下标且要求时间复杂度是O(logn),此时可以考虑使用二分查找的方法.

使用二分查找的注意事项:

1. while循环语句中边界条件,是left < right 还是left <= right,一般如果是左闭右闭的区间,我们考虑写成left <= right,如果是左闭右开的情况下写成left < right (大部分题目中这两种区间出现的概率最大,左开右闭区间出现的频率很低,所以这里不做讨论);其实这里不需要记忆,只需要遵循一个原则,在左闭右闭或者左闭右开的时候,left和right能不能相等,或者说left = right的时候这个区间是否有效即可;

2.while循环体内left和right下标如何更新,写成right = mid - 1还是right = mid,一般当你while循环中的判断语句写成left <= right时,更新下标就用right = mid - 1,反之写成right = mid;

二分查找的两种写法:

法一(左闭右闭的区间):

区间的定义,决定了二分查找的代码如何书写,因为target在[left,right]区间,所以有:

  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=;
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1.
public int binarySearch(int[] nums,int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;//这里为了防止left+right之后数据溢出
            if(nums[mid] < target) {
                left = mid + 1;
            } else if(nums[mid] > target) {
                right = mid - 1;
            } else {
                //找到返回下标
                return mid;
            }
        }
        //没有找到返回-1
        return -1;
    }

法二(左闭右开的区间):

  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的;
  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle].
public int binarySearch(int[] nums,int target) {
        int left = 0;
        int right = nums.length;//因为此时区间是左闭右开 所以right定义为数组的长度
        while (left < right) {
            int mid = left + (right - left) / 2;//这里为了防止left+right之后数据溢出
            if(nums[mid] < target) {
                left = mid + 1;
            } else if(nums[mid] > target) {
                right = mid;//因为是左闭右开的区间
            } else {
                //找到返回下标
                return mid;
            }
        }
        //没有找到返回-1
        return -1;
    }

LeetCode实例:

二分查找:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

题目链接:力扣

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值