【Leetcode算法专题】:二分查找(1)

1.经典的不能在经典的二分查找(难度⭐)

Leetcode链接:704. 二分查找

1.1题目描述:

        这是一道非常典型的二分查找算法题目,可以说所有要学习二分查找算法的人都必须掌握这道题。题目要求很简单,就是在一个有序数组中查找目标值target。这道题是二分查找算法的入门题和模版题,没有掌握这道题就无法开始学习更复杂的二分查找算法题目。所以这道题对于二分查找算法的理解和掌握非常关键和必要。

1.2代码:

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

通过这道二分查找的典型题,我对二分查找算法的理解更进一步:

我对二分查找的区间划分有了更深的理解:

  • 当mid位置的值小于target时,证明左区间[left, mid-1]都不可能存在target,所以左区间变为[mid+1, right]。
  • 当mid位置的值大于target时,证明右区间[mid+1, right]都不可能存在target,所以右区间变为[left, mid-1]。
  • 当mid位置的值等于target时,就找到了目标值。

我理解到二分查找的本质就是通过比较中间mid值与target的值,可以排除一半的搜索区间,使搜索范围越来越小,直到找到target。

通过这道题我对二分查找算法模板有了更加熟练的掌握,可以应用到其他二分查找题目中去。

2.在排序数组中查找元素的第一个和最后一个位置(难度⭐⭐)

Leetcode链接:34. 在排序数组中查找元素的第一个和最后一个位置

2.1题目描述:

2.2代码:

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int left = 0, right = nums.size() - 1, begin = -1, end = -1, mid;
        //找到区间左边界
        while(left<=right)
        {
            mid = (left + right)/2;
            if(nums[mid] > target)
            {
                right = mid - 1;
            }
            else if(nums[mid] < target)
            {
                left = mid + 1;
            }
            else
            {
                begin = mid;
                right--;//right区间左移,使得mid左移,直到到达左区间边界,此时right正好和left重合
            }
        }

        left = 0, right = nums.size() - 1;

        //找到区间有边界
        while(left<=right)
        {
                        mid = (left + right)/2;
            if(nums[mid] > target)
            {
                right = mid - 1;
            }
            else if(nums[mid] < target)
            {
                left = mid + 1;
            }
            else
            {
                end = mid;
                left++;//left区间右移,使得mid右移,直到到达又区间边界,此时left正好和right重合
            }
        }
        return {begin,end};
    }
};

这道题的大思路和上面的题并没有太大区别,只是为了找到左右区间,需要两次二分查找

具体来说,在求左右区间边界时,处理mid==target的情况需要进行特别考虑:

  • 求左区间边界时,需要在记录begin索引后,继续将right索引左移,使得mid向左逼近,直到不等于target时才能锁定左区间边界。
  • 求右区间边界时,需要在记录end索引后,继续将left索引右移,使得mid向右逼近,直到不等于target时才能锁定右区间边界。

这种细微的逻辑调整体现了二分查找的灵活性,在保持模板框架不变的情况下,通过简单逻辑修改就可应对新的问题。

 总结:

二分查找有一定的模板,灵活运用才能解决更多问题~

我们再接再厉,慢慢攻破算法大门!~

祝你快乐刷题每一天~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步亿丢丢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值