所以说我有一个排序数组:
{ 1, 2, 3, 4, 5, 6 }
我想知道是否存在三个总和为14的元素。
3 + 5 + 6 = 14
我很确定在O(N)时间内无法做到这一点,但我认为可以用O(N ^ 2)来完成。
答案 0 :(得分:5)
此问题与3SUM problem类似,可以在O(N^2)
中完成。 This java工作代码完成此任务。
// The function prints the values if there exists 3 distinct indices
// in the array arr that sum to req.
void run(){
int[] arr = { 1, 2, 3, 4, 5, 6 };
int req = 14;
// For the algorithm to work correctly, the array must be sorted
Arrays.sort(arr);
for(int i=0; i<arr.length; i++){// Iterate over the elements of the array.
// Check in linear time whether there exists distinct indices
// lo and hi that sum to req-arr[i]
int lo=0, hi = arr.length-1;
boolean found = false;
while(lo<hi){
if(lo==i){
lo++;
continue;
}
if(hi==i){
hi--;
continue;
}
int val = arr[lo] + arr[hi] + arr[i];
if(val == req){
System.out.println(arr[lo] + " + " + arr[hi] + " + " + arr[i] + " = " + req);
found = true;
break;
}else if(val < req){
lo++;
}else{
hi--;
}
}
if(found)break;
}
}
答案 1 :(得分:2)
答案 2 :(得分:0)
这类似于子集总和问题,即NP-Complete
但是将子集长度限制为3,可以找到快速解决方案
您的问题等同于3SUM problem.
您的问题中r
= K
。
伪代码: O(N ^ 2)
for (i in 1..n-2)
{
j = i+1 // Start right after i.
k = n // Start at the end of the array.
while (k >= j) {
// done.
if (A[i] + A[j] + A[k] == r) return (A[i], A[j], A[k])
// We didn't match. Let's try to get a little closer:
// If the sum was too big, decrement k.
// If the sum was too small, increment j.
(A[i] + A[j] + A[k] > r) ? k-- : j++
}
// When the while-loop finishes, j and k have passed each other and there's
// no more useful combinations that we can try with this i.
}
答案 3 :(得分:0)
如果k
与数组的大小(或更小)大致相同且所有数字都是正数(处理零是微不足道的),则可以有效地使用DP。对于从0到k
的所有数字,您记得是否可以使用数组中的零个,一个,两个或三个整数来获取它。该解决方案的时间为O(Nk)
,空间为O(k)
,并且非常易于实施。
int[] myarray = {1, 2, 3, 4, 5, 6};
int k = 14;
int[] dp = new int[k+1];
dp[0] = 1;
for (int i = 0; i < myarray.length; ++i) {
for (int j = k; j >= myarray[i]; --j) {
dp[j] |= dp[j-myarray[i]] << 1;
}
}
if ((dp[k] & 8) > 0) {
System.out.println("YES");
} else {
System.out.println("NO");
}