Bootstrap

时间复杂度优化

题目链接:16.聪明的小羊肖恩 - 蓝桥云课

1.初始代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,r;
int a[200010];
signed main()
{
	cin>>n>>l>>r;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	int sum1=0;
	for(int i=1;i<=n;i++)
	{
		int sum=0;
		for(int j=i+1;j<=n;j++) //完整一次循环是一个子区间 
		{
			sum=a[i]+a[j];
			if(sum>=l && sum<=r)
			{
				sum1++;
			}
		}
	}
	cout<<sum1<<endl;
	return 0;
}

大约能够过75%,只是对遍历进行了优化,其实没有真正利用到sort排序

2.方法一:

排序后,利用二分优化时间复杂度,首先推导出:l-a[i]<=a[j]<=r-a[j] ,然后查找所有满足条件的a[j],累加求和

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,r;
int a[200010];
signed main()
{
	cin>>n>>l>>r;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	//l-a[i]<=a[j]<=r-a[j] 
	int sum=0;
	for(int i=1;i<=n;i++)
	{
		int l1=l-a[i],r1=r-a[i];
		sum+=upper_bound(a+i+1,a+1+n,r1)-lower_bound(a+i+1,a+1+n,l1);
	}
	cout<<sum<<endl;
	return 0;
}

3.方法二:

排序后,使用双指针优化时间复杂度,双指针遍历,累加求和1-L和1-R满足条件的和

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,l,r;
int a[200010];
int sum(int x)
{
	int l1=1,r1=n,ans=0;
	while(l1<r1)
	{
		if(a[l1]+a[r1]<=x)
		{
			ans+=r1-l1;
			l1++;
		}
		else
		{
			r1--;
		}
	}
	return ans;
}
signed main()
{
	cin>>n>>l>>r;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	//容斥原理:sum[l-1...r]=sum[r]-sum[l-1]
	cout<<sum(r)-sum(l-1)<<endl;
	return 0;
}
;