这是一个我要求解决的面试问题:给定一个未排序的数组,找出数组中的2个数字及其总和。 (也就是说,在数组中找到三个数字,使得一个是另外两个的总和。)请注意,我已经看到了在给出sum(int k)时找到2个数字的问题。但是,这个问题希望您找出数组中的数字和总和。它可以用O(n),O(log n)或O(nlogn)来解决
有一个标准的解决方案,遍历每个整数,然后对其进行二进制搜索。有更好的解决方案吗?
public static void findNumsAndSum(int[] l) {
// sort the array
if (l == null || l.length < 2) {
return;
}
BinarySearch bs = new BinarySearch();
for (int i = 0; i < l.length; i++) {
for (int j = 1; j < l.length; j++) {
int sum = l[i] + l[j];
if (l[l.length - 1] < sum) {
continue;
}
if (bs.binarySearch(l, sum, j + 1, l.length)) {
System.out.println("Found the sum: " + l[i] + "+" + l[j]
+ "=" + sum);
}
}
}
}
答案 0 :(得分:4)
这与标准问题3SUM
非常相似,右边的许多相关问题都与此有关。
您的解决方案是O(n^2 lg n)
;有O(n^2)
个算法based on sorting the array,对此变体略有修改。最着名的下限是O(n lg n)
(因为你可以使用它来执行比较排序,如果你很聪明的话)。如果你能找到一个子二次算法或一个更严格的下界,你会得到一些出版物。 :)
请注意,如果您愿意将整数限制在[-u, u]
范围内,那么使用Fast Fourier Transform可以及时解决a + b + c = 0
问题O(n + u lg u)
。但是,对我来说,如何将其调整为a + b = c
问题并不是很明显。
答案 1 :(得分:2)
您可以在O(nlog(n))
中解决此问题,如下所示:
以O(nlog(n))
递增排序数组。您需要2个索引指向数组的左/右端。让我们称他们为i
和j
,i
为左边,j
为右边。
现在计算array[i] + array[j]
的总和。
k
,请将j
减少一个。k
。将i
增加一个。重复直到总和等于k
。
因此,使用此算法,您可以在O(nlog(n))
中找到解决方案,并且实现起来非常简单
对不起。好像我没有仔细阅读你的帖子;)