【发布时间】:2021-12-09 15:49:11
【问题描述】:
问题陈述给定一个数组和一个给定的总和“T”,找到数组中元素的所有索引对,加起来为 T。附加要求/约束:
- 索引从 0 开始
- 索引必须首先显示较低的索引(例如:24、30 而不是 30、24)
- 索引必须按升序显示(例如:如果我们找到 (1,3)、(0,2) 和 (5,8),则输出必须是 (0,2) (1,3) (5 ,8)
- 数组中可能存在重复元素,这也是必须考虑的
这是我的 C++ 代码,我使用了 unordered_set 的哈希表方法:
void Twosum(vector <int> res, int T){
int temp; int ti = -1;
unordered_set<int> s;
vector <int> res2 = res; //Just a copy of the input vector
vector <tuple<int, int>> indices; //Result to be output
for (int i = 0; i < (int)res.size(); i++){
temp = T - res[i];
if (s.find(temp) != s.end()){
while(ti < (int)res.size()){ //While loop for finding all the instances of temp in the array,
//not part of the original hash-table algorithm, something I added
ti = find(res2.begin(), res2.end(), temp) - res2.begin();
//Here find() takes O(n) time which is an issue
res2[ti] = lim; //To remove that instance of temp so that new instances
//can be found in the while loop, here lim = 10^9
if(i <= ti) indices.push_back(make_tuple(i, ti));
else indices.push_back(make_tuple(ti, i));
}
}
s.insert(res[i]);
}
if(ti == -1)
{cout<<"-1 -1"; //if no indices were found
return;}
sort(indices.begin(), indices.end()); //sorting since unordered_set stores elements randomly
for(int i=0; i<(int)indices.size(); i++)
cout<<get<0>(indices[i])<<" "<<get<1>(indices[i])<<endl;
}
这有多个问题:
- 首先,while 循环没有按预期工作,而是显示
SIGABRT错误(free(): invalid pointer)。ti索引也以某种方式超出了向量范围,即使我在 while 循环中进行了检查。 - 其次,
find()函数在 O(n) 时间内工作,这将整体复杂度增加到 O(n^2),这导致我的程序在执行期间超时。然而,这个函数是必需的,因为我们必须输出索引。 - 最后,当数组中有许多重复元素时,
unordered-set实现似乎不起作用(因为集合只采用唯一元素),这是问题的主要限制之一。这让我觉得我们需要某种哈希函数或哈希图来处理重复项?我不确定...
我在互联网上找到的所有不同算法都只处理打印元素而不是索引,因此我没有解决这个问题。
如果你们中的任何人知道一个最佳算法,同时满足约束并在 O(n) 时间下运行,我们将非常感谢您的帮助。提前谢谢你。
【问题讨论】:
-
您的算法无法在
O(n)时间内运行。如果您的数组中填充了1s 和T=2,那么将有O(n²)对满足您的要求的索引。因此,您的输出大小可能为O(n²)。至于在小于O(n)的情况下运行,那就更难了,因为在数组中简单查找元素需要O(n)操作。 -
@m.raynal 我知道,这就是为什么我要问是否有更好的优化算法来解决这个问题,它适用于索引。
-
理论上(大O复杂度),这是同样的问题。在实践中,您可以开始构建一个映射,其中键是元素,值是与该元素对应的索引集。然后,您可以应用适用于元素的算法,并迭代相应索引的所有组合。如果阵列中有很多冗余,它应该在实践中带来不错的加速。如果这是你要找的,我可以用这个算法写一个答案
-
@m.raynal 是的,这可能只是工作,是的,请您的完整答案真的很有帮助????????
标签: c++ algorithm vector hashtable sigabrt