二分法

本文讲解了如何利用二分法解决代号C-137的地球问题,通过计算篮球间的磁力最大化,揭示了在给定位置条件下如何找到最大最小磁力。通过实例演示和C++代码,展示了二分法在寻找满足条件的最优解决方案中的效率。
摘要由CSDN通过智能技术生成

二分法

二分法的思想很简单,确定好上下界,取中间的数,看是否符合条件,若是则将下界更新为中间数后的一位。即每次循环都将当前范围分成两份,然后抛弃不符合题意的一半,显然它的时间复杂度为O(log 2n) 。它适用于较长的数组,并且数组元素必须是排好序的。

比如给出一个数组array[10]={1,2,3,4,5,6,7,8,9,10};查找数组中是否含有8,是则输出“Yes”,否则输出“No”。

首先它是排好序的,符合条件,我们使用二分法:

定义上下界分别为10和1,中间数为(1+10)/2=5,5<8,所以保留后半部分,下界更新为5+1=6;中间数为(6+10)/2=8,找到了,循环结束。

C++代码:

#include<iostream>
using namespace std;
int main(){
    int array[10]={1,2,3,4,5,6,7,8,9,10};
    int low=array[0],high=array[9],mid;
    while(low<=high){
        mid=(low+high)/2;
        if(mid>8){
            high=mid-1;//更新上界
        }
        else if(mid<8){
            low=mid+1;//更新下界
        }
        else{//找到了
            cout<<"Yes"<<endl;
            return 0;
        }
    }
    //没找到
    cout<<"No"<<endl;
    return 0;
}

最主要的就是选择上下界,然后实现循环。

例题

在代号为 C-137 的地球上,Rick 发现如果他将两个球放在他新发明的篮子里,它们之间会形成特殊形式的磁力。Rick 有 n 个空的篮子,第 i 个篮子的位置在 position[i] ,Morty 想把 m 个球放到这些篮子里,使得任意两球间 最小磁力 最大。

已知两个球如果分别位于 x 和 y ,那么它们之间的磁力为 |x - y| 。

给你一个整数数组 position 和一个整数 m ,请你返回最大化的最小磁力。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/magnetic-force-between-two-balls


解析:这题如果使用二分法求解,首先就是要找到上下界,对应到题目中就是m个球之间可能的最小距离。 最小距离的最大值,就是在篮子全部相邻的情况下,此时最小距离为n/(m-1),最小距离的最小值我们设为1。那么我们只需要二分这个区间,查找到数组position能够满足的最大的最小距离即可。定义一个check函数用于判断数组position能否实现这个最小距离。

C++代码:

    bool check(vector<int> v,int m,int n){
        int former,latter,count=0,i=0,j=1;
        while(j<=v.size()-1){
            former=v[i];
            latter=v[j];
            if(latter-former>=n){
                count++;
                i=j;
            }
            j++;
        }
        if(count>=m-1){
            return true;
        }
        else{
            return false;
        }
    }
    int maxDistance(vector<int>& position, int m) {
        int len=position.size(),mayAns;
        sort(position.begin(),position.end());
        int high=(position[len-1]-position[0])/(m-1),low=1,mid;
        while(low<=high){
            mid=(high+low)/2;
            if(check(position,m,mid)){
                low=mid+1;
                mayAns=mid;
            }
            else{
                high=mid-1;
            }
        }
        return mayAns;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值