Java 给定一个排序整数数组,如何找到是否存在一组3个元素和为K?

Java 给定一个排序整数数组,如何找到是否存在一组3个元素和为K?,java,arrays,algorithm,Java,Arrays,Algorithm,假设我有一个排序数组: { 1, 2, 3, 4, 5, 6 } 我想看看是否有三个元素加起来等于14 3 + 5 + 6 = 14 我很确定在O(N)时间内没有办法做到这一点,但我认为它可以在O(N^2)时间内完成。这类似于子集和问题,它是NP完全。 但将子集长度限制为3,可以找到快速解决方案。 您的问题相当于 r=K就像你的问题一样 伪代码:O(N^2) for (i in 1..n-2) { j = i+1 // Start right after i. k = n

假设我有一个排序数组:

{ 1, 2, 3, 4, 5, 6 }
我想看看是否有三个元素加起来等于14

3 + 5 + 6 = 14

我很确定在O(N)时间内没有办法做到这一点,但我认为它可以在O(N^2)时间内完成。

这类似于子集和问题,它是NP完全。
但将子集长度限制为3,可以找到快速解决方案。
您的问题相当于
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.
}

此问题类似于,可以在
O(N^2)
中完成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;
        }
    }
//如果存在3个不同的索引,该函数将打印值
//在数组arr中,求和为req。
无效运行(){
int[]arr={1,2,3,4,5,6};
int req=14;
//为了使算法正确工作,必须对数组进行排序
数组。排序(arr);

对于(int i=0;i,在计算理论中,这被称为问题。迄今为止发现的这个问题的最佳解决方案成本为O(N^2)。能否以更好的成本解决这个问题仍然是一个悬而未决的问题。您可以找到这个算法的一个实现。

如果
k
与数组大小大致相同(或更小)所有的数字都是正数(处理零很简单),可以有效地使用DP。对于从0到
k
的所有数字,您可以记住是否可以使用数组中的零、一、二或三个整数来获得DP。解决方案在时间上是
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");
}
int[]myarray={1,2,3,4,5,6};
int k=14;
int[]dp=新的int[k+1];
dp[0]=1;
对于(int i=0;i=myarray[i];--j){
dp[j]|=dp[j-myarray[i]]0){
System.out.println(“是”);
}否则{
系统输出打印项次(“否”);
}

@Maroun不,这没有多大帮助here@downvoter我的算法是绝对正确的!为什么你投了否决票?至少要评论一下。我没有投否决票,但条件
A[I]+A[j]+A[k]==0
似乎不正确:)这似乎是从这里得到的。评论完全一样。@downvoter请解释为什么投否决票?(没有向下投票)看起来像一个for循环包含一个二进制搜索,你能解释一下为什么时间复杂度是O(N^2)吗?内循环是O(N)。我们只查看数组的每个元素一次。外数组是O(N)。所以算法是O(N^2)。是的,明白了,谢谢:)为什么这个回答被挂起?O。O他的活动日志在我看来还行。