二分查找基础模板

二分查找基础模板

704.二分查找

LeetCode题目链接
在这里插入图片描述

思路

能够使用二分法的前提是给定的数组是升序数组或者是降序数组(有序数组),同时如果题目中强调数组中是没有重复元素的,那么使用二分法返回的元素下标就会是唯一的。

二分法主要涉及的麻烦问题在于边界条件,即到底是使用while(left<right)还是while(left<=right),是使用left=middle还是left=middle+1(right也是同理)。

解决上述边界问题的关键点在于我们如何设定left和right。一般情况下left和right有两种设定方式:

1.left和right涵盖了题目所给数组的左闭区间和右闭区间,即假设数组下标从0开始,长度为n,则涵盖了左闭区间和右闭区间的含义是left=0,right=n-1。

2.left和right涵盖了题目所给数组的左闭区间和右开区间,即假设数组下标从0开始,长度为n,则涵盖了左闭区间和右开区间的含义是left=0,right=n。

首先我们假定想要取得的目标值为target。

对于第一种设定方式,二分法应该如下操作:

因为第一种设定方式target在[left,right]区间,所以在设置while(left<=right)时,是要加等于号的,因为加上等于号,区间仍然是有意义的。

同时在设置left=middle+1right=middle-1时,是要进行对应的加或者减的,因为当if(nums[middle]<target)或者是if(nums[middle]>target)时,根据判断式,我们已经可以知道middle这个下标所代表的数组的值是不等于target的,所以我们在设置left或者right时,需要将其去除。

根据上述的解释,我们可以得到第一种二分法的代码:

class Solution {
    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<=right)
        {
            int middle=left+((right-left)/2); //防止溢出,其实就是(left+right)/2
            if(nums[middle]>target)
            {
                right=middle-1;
            }
            else if(nums[middle]<target)
            {
                left=middle+1;
            }
            else{
                return middle;
            }
        }
        return -1;
    }
}

对于第二种设定方式,二分法应该如下操作:

因为第二种设定方式中target是在[left,right)区间,所以在设置while(left<right)时,是不能加上等于号的,因为加上等于号会使得区间变得没有意义。

同时在设置left=middle+1right=middle时,left是需要进行对应的加一的,因为left所代表的是闭区间,而right是不需要进行减一的,因为right所代表的是开区间。(具体的解释和第一种方式相同)

根据上述的解释,我们可以得到第二种二分代码:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值