【LeetCode】704.二分查找

【LeetCode】704.二分查找

思路

题目强调了是一个有序(升序)的数组,且提示中说明元素不重复,这样就满足了使用二分法的条件,我们只需要处理好边界就好。

在全闭区间[left,right]的代码

class Solution {
public:
    int search(vector<int>& nums, int target) {
        //1.确定要寻找元素的闭区间[left,right]
        int left = 0;
        int right = nums.size()-1;
        //2.在[left,right]的闭区间寻找元素
        while(left<=right)
        {
            int mid = (left+right)/2;//注意mid写在循环内,每次循环开始更新mid
            if(target>nums[mid])//下面有解析
            {
                left=mid+1;
            }
            else if(target<nums[mid])
            {
                right = mid-1;
            }
            else
            {
                return mid;//target与nums[mid]相等返回下标
            }
        }
        //3.找不到返回-1
        return -1;
    }
};

解析

以下图为例

target=9时,nums[mid]<target ,故下一次的查找区间为[mid+1,right],即[4, 6]。

同理,若target=0时,nums[mid]>target,下一次的查找区间为1[left,mid-1],即[0, 2]。

target=5时,直接返回mid,下标对应3

所以若target=6不再数组中,我们只需要在循环结束后返回-1,说明找不到。

循环结束标志

这里在left<=right的时候进入循环,当right>left时,left与right间没有元素,自然要出循环。

至于为什么有=,我们以单元素数组[1]为例,此时left=mid=right=0,无论target等于几,我们仍需要再数组[1]中查找一番,所以需要=。

若有开区间怎么处理

上面我们给出了全闭区间[left,right]处理的解析,如果要处理的是[left,right)呢?

首先我们可以想到的是将问题转化为处理[left,right-1),再复用上面的思想。

那如果要单独处理呢?

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size()-1;
        while(left<right)
        {
            //这里left=right没有进入循环的意义了
            int mid = (left+right)/2;
            if(target>nums[mid])
            {
                left=mid+1;//更改搜索区间为[mid+1,right]
            }
            else if(target<nums[mid])
            {
                right = mid;//更改搜索区间为[left,mid)
            }
            else
            {
                return mid;
            }
        }
        return -1;
    }
};

解析

我们仍然以此图为例:

对于target=9而言,nums[mid]<target,查找的区间为从[left,right)变为[mid+1,right),即left=mid+1。

对于target=0而言,nums[mid]>target,查找的区间从[left,right)变为[left,mid],即right=mid。

循环结束标志

为什么是left<right,没有了=呢,以单元素数组[1]为例,此时left=mid=right=0,我们要查找的区间变成了[0,0),我们认为这样没有意义。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值