二分搜索详解

二分难点

二分的主要难点在于两个:

  1. 找到一个单调的序列
  2. 确定需要搜索的目标,并且确定使用怎样的条件去缩小范围
  3. 边界条件与题目所求是否对应(确定返回值的含义)

第一个主要是证明,因为有的题不是直接给一个序列让你搜索,像母题一样,而是藏在更深的地方。所以这个要视情况而定

第三个参考https://leetcode.cn/problems/maximum-value-at-a-given-index-in-a-bounded-array/solution/by-lao-song-2f-n5b6/

模板

概括为一共有两个模板:

  1. 搜索大于target的第一个元素 =====》 upper_bound()
     int l = 0, r = nums.size()-1;
     while(l<=r){
     	int mid = (l+r)/2;
     	if(nums[mid]>target) r = mid-1;
     	else l = mid+1;
     }
     return l; //代表第一个大于target的下标
  1. 搜索大于等于target的第一个元素 =====》lower_bound()
      int l = 0, r = nums.size()-1;
      while(l<=r){
      	int mid = (l+r)/2;
      	if(nums[mid]>=target) r = mid-1;
      	else l = mid+1;
      }
      return l; //代表第一个大于等于target的下标

两者的区别主要就是if后面的判断语句有没有等号。思考方式是,while循环跳出的情况只可能是跳出前lrmid,此时若nums[mid]>=target,则r=mid-1,此时l就大于r了,下一次就进不了while了。但关键在于l没变位置(还是l==r时的位置),那么当时的情况是nums[mid]>=target,说明l(==mid)是使得nums[l]大于等于目标值的第一个下标。else里的情况也是一样思考,得出的结论相同。

其他

灵活运用这两个模板才是关键

举个例子:当题目要求重复元素中的第一个时,使用第二个模板,此时;当题目要求重复元素的最后一个时,使用第一个模板;

当题目要求 求小于target的最后一个元素时,那么反过来其实就是求大于等于target的第一个元素,那么用第二个模板求出的l-1就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值