整数二分模板(附实例)

“ Ctrl AC!一起 AC!”

目录

前言:

模板一:找最大优解

模板二:找最小优解

实例一:(模一套用)

实例二:(模二套用)


前言:

二分算法的模板多到有点恐怖,但它们基本都只是实现了两种算法:所有解中找最大优解、所有解中找最小优解。(那我(们)干脆每种记一个模板就够了,鄙人很懒,你们随意咯)。

至于二分算法的模板为什么有很多,那是因为

1.退出循环的选while(l<r) 还是选 while(l<=r) 。

2. 什么时候用 l=mid,l=mid-1,l-mid+1,r=mid,r=mid+1,r=mid-1里面的哪两个组合。

3. 答案是mid 还是 r 还是 l。

其实熟悉二分的同学可以直接推理出来,就不需要固定的模板。那么对于刚入门的同学可以背背模板,慢慢熟悉。

模板一:找最大优解

int l = 0, r = len - 1, int mid;
while (l < r) {
	mid = (l + r + 1) / 2; //+1不理解可自己模拟一遍 或评论区见
	if (check(mid)) l = mid; //mid可以就往右走,找更大的值,范围变为[mid,r]
	else r = mid - 1; //mid不行就往左走,范围变为[l,mid-1]
}
int ans = l || r;

模板二:找最小优解

int l = 0, r = len - 1, int mid;
while (l < r) {
	mid = (l + r) / 2;
	if (check(mid)) r = mid; //mid可以就往左走,找更小的值,范围变为[l,mid]
	else l = mid + 1; //mid不行就往右走,范围变为[mid+1,r]
}
int ans = l || r;

实例一:(模一套用)

题目: 查找插入位置

分析:这题想要套用模板一的话,就要找比target小的数里面的最大值,然后下标加一。但是这里有特殊情况,就是如果没有比target小的数的话,就要返回0。

AC代码:

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int len=nums.size();
        int l=0,r=len-1;
        //模板一套用
        while(l<r){
            int mid=(l+r+1)/2;
            if(nums[mid]<target) l=mid;
            else r=mid-1;
        }
        if(l==0&&nums[l]>=target) return 0; //判断特殊情况
        return l+1;
    }
};

实例二:(模二套用)

题目:公平的糖果交换

分析:这道题首先找出两人糖果总数差,再除二 设为change,遍历第一个人的每盒糖果。

设delt=num1[i]-change, 我们只需在第二个人的数组num2中找有没有delt就行。

交换这两盒,就能达到目的。套用模板二后需要判断条件。

AC代码:

class Solution {
public:
    vector<int> fairCandySwap(vector<int>& aliceSizes, vector<int>& bobSizes) {
        vector<int> answer;
        int len1=aliceSizes.size();
        int len2=bobSizes.size();
        int sum1=0,sum2=0;
        for(int i=0;i<len1;i++){
            sum1+=aliceSizes[i];
        }
        for(int j=0;j<len2;j++){
            sum2+=bobSizes[j];
        }
        int change=(sum1-sum2)/2;
        sort(bobSizes.begin(),bobSizes.end());//二分前提:排序
        for(int i=0;i<len1;i++){
            int delt=aliceSizes[i]-change;
            int l=0,r=len2-1;
            //套用模板二
            while(l<r){
                int mid=(l+r)/2;
                if(bobSizes[mid]<delt) l=mid+1;
                else r=mid;
            }
            //因为可能根本找不到delt,所以要判断
            if(bobSizes[l]==delt){
                answer.push_back(aliceSizes[i]);
                answer.push_back(bobSizes[l]);
                break;
            }
        }
        return answer;
    }
};

更多模板见:

@浮点数二分模板(附实例)

@while(l<=r)二分模板

@整数\\实数二分

感谢阅读!!!

“ Ctrl AC!一起 AC!”

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ctrl AC

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

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

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

打赏作者

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

抵扣说明:

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

余额充值