第十天:整数查找(二分查找)

今天是释然发题解的第十天,以后每一天都会和大家分享学习路上的心得,希望和大家一起进步,一起享受coding的乐趣。
本文约1200字,预计阅读4分钟
昨天我们学习了二分,忘记的小伙伴们可以看一下哦:

二分查找

今天我们来聊一聊的二分的相关问题,明天和大家分享分治的相关知识:

题目:整数查找

题目来源:改编
题目描述:输入n(n<=1e6)个数从中间寻找两个数,使得这两个数的和为m
输入:第一行一个数n,第二行n个数
对于20%的数据:n<=100
对于40%的数据:n<=10000
对于100%的数据: n<=1e6

解题思路一:二重循环(模拟)

暴力求解:我们就一个一个找,相加求和不就行了?
碰到按照测试点得分问题我们可以混分

for(int i=1;i<=n-1;i++)
{
	for(int j=i+1;j<=n;j++)
	{
		if(a[i]+a[j]=n) break;
	}
}

对于这个方法,想过50%的数据点还是可能卡过去的,也就是说一半的分可以模棱两可混过去,但是在一般的比赛上,一看到这个是O(n^2)的复杂度基本上是过不去的,最后一题连O(n)都可能会超时

解题思路二:二分查找

我们知道想用二分查找,必须先排序:

//C++中自带sort函数,时间复杂度为O(nlogn)
#include<algorithm>
sort(a,a+n);
升序降序无所谓

这个思路就是:第i个数,我们在数组中查找(n-i)看看能不能找到,排序时间复杂度为nlogn,查找最多需要n-2次,复杂度为logn,因此时间复杂度为nlogn

int lastnum,pos,n;
int a[n];
int lowerbound(int *a,int l,int r,int num)
{
    int mid;
    int lastpos=0;
    while(l<r)
    {
        mid=(l+r)/2;
        if(a[mid]==num)
        {
            return mid;
        }
        else
        {
            if(a[mid]>num)
        {
            
            r=mid;
        }
        else 
        {
            l=mid+1;
        }
    }     }
    return lastpos;
}
int mian()
{
for(int i=1;i<=n-i;i++)
{	if(lastnum==i) continue;
	lastnum=i;//减少不必要的查找
    pos=lowerbound(a,i,n,n-a[i]);
	if(pos)
	{
		cout<<a[i]<<a[pos]<<endl;
		return 0;
	}
}
}

解题思路三:用数组进行二分查找:

我们还是先排序(升序),然后呢我们用两个指针一个左指针一个右指针,如果a[i]+a[j]>n,我们就j–,如果a[i]+a[j]<n,我们就让i++,直到i=j为止
这个算法时间复杂度还是nlogn

while(a[i]+a[j]!=n)
    {
        if(a[i]+a[j]>n)
        {
            j--;
        }
        else
        {
            i++;
        }
     }
    cout<<a[i]<<a[j]<<endl;

好了,今天的有关二分查找的题目就到这里
释然每天发布一点自己学习的知识,希望2年后我们也能在ACM的赛场上见面,一起去追寻自己的程序猿之路吧!

后期也会和大家一起分享学习心得和学习经验呢,明天我们不见不散哦!

下期预告:

分治和贪心

如果大家有什么建议或者要求请后台留言,释然也想和大家一起进步呀!
联系方式:shirandexiaowo@foxmail.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Shirandexiaowo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值