给定n
,数组中的术语数量k
,正数和数组arr[]
,预计会找到数组中的对数,以便他们的差异至少为k
EX:
INPUT
7 2
2 4 3 5 6 1 7
输出
15
所以我的方法是:
int main()
{
long long int n,k;
scanf("%lld %lld",&n,&k);
long long int a=0,arr[n];
while(a<n)
{
scanf("%lld",&arr[a]);
a++;
}
quicksort(arr,0,n-1);//sorting the array
long long int i=n-1,j=0,ans=0;//two-pointer method
while(i>0)
{
if(arr[i] - arr[j] >= k && j < i)
{
ans ++;
j++;
}
else
{
i--;
j = 0;
}
}
printf("%lld",ans);
return 0;
}
但解决方案超出了较大测试用例的时间限制。有可能改进吗?
答案 0 :(得分:1)
您可以在此问题中使用二进制搜索。对数组进行排序后,您可以K
为x
找到每个元素K+x
的差异大于i
的对。找到索引K+x
之后,其后的元素的值都等于或大于total = 0
sort(arr)
for each x in arr:
i = lower_bound(K+x)
total += arr.size - i
,您可以轻松解决问题。
repartition
答案 1 :(得分:1)
实际上,你只能将答案增加1.在对数组进行排序后,我会从底部运行两个索引变量。增加上部索引,直到元素的差异为&gt; = k
。然后我知道与以下所有元素的区别也是&gt; = k
所以可以将数组的剩余长度添加到答案中。然后增加底部索引,再次添加剩余数组的长度,直到差值<1。 k
。所以底部索引沿着数组追逐顶部索引,只需要一次传递。
答案 2 :(得分:1)
可以在while循环中进行改进。您正在搜索满足给定条件的所有元素。我们可以通过搜索一个元素来利用排序(例如b,因为arr [i] + k <= b),后续元素将始终满足条件,从而减少搜索。
int n,k;
cin>>n>>k;
std::vector<int> v(n,0);
for(int i = 0;i < n;++i)
cin>>v[i];
sort(v.begin(),v.end());
std::vector<int> ::iterator it;
int result = 0;
for(int i = 0;i < n; ++i){
int a = v[i];
it = lower_bound(v.begin(),v.end(),a+k); // find the element that satisfies a + k <= b
if(it != v.end())
result += n - (it - v.begin()); // number of elements which are more than b
}
cout<<result<<"\n";