数据结构算法之-----二分查找

二分查找原理是并不难的,就是从一个有序数组中找到想要的target,但是对于边界问题是比较难把握的,下面就分享一下:

(1)左闭右闭区间
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0;
        int right=nums.size()-1;
        while(left<=right)
        {
            int middle=(left+right)/2;
            if(nums[middle]>target)
            {
                right=middle-1;
            }
            else if(nums[middle]<target)
            {
                left=middle+1;
            }
            else{
                return middle;
            }

        }
        return -1;
    }
};

         为什么这个称为左闭右闭区间呢,因为算法中left是从0开始取的,而右边界right是从n(数组长度)-1开始取,都是能取到的,所以是左闭右闭区间,首先循环进行的条件到底是“<”还是“<=”,打个比方,[0,0]这个区间是不是合法的呢,当然是,因为区间里只有一个数字0,那么left能不能等于right呢,答案是yes,所以结束条件是left>rigth时循环结束。

        我们找到middle之后,如果nums[middle]是大于target的,证明我们的target在左区间内,因此要移动right,此时到底是取middle-1还是取middle呢,答案是middle-1,因为我们在判断的时候已经判断了此时的nums[middle]是大于target的,那middle下标对应的值就不需要再被拿来查找了,所以是middle-1.同理,当nums[middle]<target时,需要移动left,也是同理,应该取middle+1

(2)左闭右开区间
class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left=0,right=nums.size();
        while(left<right)
        {
            int middle=(left+right)/2;
            if(nums[middle]<target)
            {
                left=middle+1;
            }
            else if(nums[middle]>target)
            {
                right=middle;
            }
            else
            {
                return middle;
            }
        }
        return -1;
    }
};

        这次和上面的区别是右边界right取到了nums.size(),但实际数组下标是没有的,所以右边是开区间,那我们循环进行的条件是什么呢,同理[0,0)是不是合法区间呢,当然不是,所以条件就是left<right。

        那么当nums[middle]>target时,要移动左区间left的值,是取middle还是middle+1呢,我们已经判断了middle位置对应的值是不满足条件的,那么肯定是取middle+1处的值,因为左区间是闭区间,是可以取到的;当nums[middle]<target时,要移动右区间right的值,该取什么呢,仔细想想,当前middle位置的值显然已经不满足,但是右区间是开区间,middle处的值是取不到的,所以只需要让right=middle就可以,这就解决了边界问题,希望对大家能有帮助。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值