差异至少为K的数字对数

时间:2016-09-16 09:26:47

标签: c algorithm performance time

给定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;
}

但解决方案超出了较大测试用例的时间限制。有可能改进吗?

3 个答案:

答案 0 :(得分:1)

您可以在此问题中使用二进制搜索。对数组进行排序后,您可以Kx找到每个元素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";