【问题标题】:Find indices i<j in an array of size n so that the sum of values at those indices is equal to i + j在大小为 n 的数组中查找索引 i<j,以便这些索引处的值之和等于 i + j
【发布时间】:2018-11-18 11:26:06
【问题描述】:

我的解决方案:

#include <bits/stdc++.h>

int main() {
    int n;//Size of array
    std::cin>>n;
    std::vector<long long>vec_int;
    int temp = n;
    while(n--){
        long long k ;
        std::cin>>k;
        vec_int.push_back(k);
    }
    n = temp;
    int num = 0;
    for(int  i = 0 ; i < n-1 ; i++){
        for(int j = i+1; j<n; j++){
            if(i<j && i+j == vec_int[i]+vec_int[j])
                num++;
        }
    }

    std::cout<<num;

    return 0;
}

我正在扫描大约需要O(n^2) 时间的阵列。在非常大的数组上,问题的时间限制超过了 2 秒的持续时间。我尝试对数组进行排序,但没有走得太远。我怎样才能加快速度?是否可以在O(n) 时间复杂度内做到这一点。

【问题讨论】:

  • 因此,对于数组[2,1,3,8,6,5] ij15。对吗?
  • 另外,在您的代码中i&lt;j 是一个冗余检查。
  • 是的。 i 上升到倒数第二个元素。 j 转到最后一个元素。我将删除冗余,但仍然没有解决问题。
  • 现在,为什么这被否决了?有什么解释吗?我做错了什么?
  • 我没有投反对票,是的,我正在看看是否有更好的解决方案。

标签: c++ arrays algorithm sorting


【解决方案1】:

考虑重新定义您的问题。表达式:

i+j == vec_int[i]+vec_int[j]

在代数上等价于:

vec_int[i] - i == -(vec_int[j] - j)

所以定义:

a[i] = vec_int[i] - i

现在的问题是计算a[i] == -a[j] 的次数。

这可以在O(n) 中测试。使用unordered_map m 计算每个负值在a 中出现的次数。然后对于每个正值 a[i] 将与 m[-a[i]] 负值配对。还要计算a 中零的数量并计算它们之间的对数。

【讨论】:

  • 很好的观察!
  • 注意stackoverflow.com/questions/53343473/…上同一问题的相似但不同的答案
  • 在我看来,使用 unordered_map 将是 O(nlogn)
  • @Damien, unordered_map 具有平均恒定时间访问权限。
  • 我在考虑结构,而不是访问,但实际上我错了。对于非常大的 n,您的方法应该比我的方法快,不确定 n 上的中间值。
猜你喜欢
  • 1970-01-01
  • 2013-08-19
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 2017-10-06
  • 2020-01-10
  • 2014-11-25
  • 2020-12-16
相关资源
最近更新 更多