繁体   English   中英

确定数组中是否存在a,b,c以便a + b + c = z?的算法 [重复]

[英]Algorithm for deciding if a,b,c exist in an array so that a+b+c = z? [duplicate]

为解决以下问题找到了有效的算法有些困难。 算法必须确定数组中是否存在3个元素a,b和c,以便a + b + c等于给定的数字z。

当然,幼稚的方法是尝试组合,但是渐近地,所需的时间会太大。

为了在数组中找到a和b使得和为z,要容易得多。 以升序对给定数组排序,并检查每个元素是否存在za。 但是我不确定如何在3元素问题中实现它以及需要什么时间。

任何帮助深表感谢!

编辑:a,b,c和z是整数。

我想我应该写一个简短的评论作为答案,但是我对此没有足够的声誉...所以这里什么也没有!


我现在可以提出的最佳算法是O(n ^ 2),为更好地解释该算法,我们将从O(n)情况下(如果不是O(nlgn)的a + b = z开始排序)

首先,迭代{a},然后找到{b},使得a + b = z。 天真的,如果您对所有b进行迭代,则每个{a}的成本为O(n),从而得出O(n ^ 2)解。 但是,如果您不断地迭代{a},则{b}的值必须严格减小。 我们可以利用此信息来减少时间复杂度,如以下代码所示:

for a = first element, b = last element; a != last; a = next a
while ( ( b != first element ) and (a + b > z) )
      b = previous elemnet of b
if a + b == z
      return true

请注意,{b}在整个循环中仅遍历整个列表一次,因此它具有分摊的O(n)复杂度。


现在我们可以将此原理应用于最初的问题,可以迭代{a},然后将此O(n)算法应用于{b,c}以找到{za},总复杂度为O(n * n = n ^ 2)。

希望有一个较低复杂度的解决方案,我不认为O(n ^ 2)令人印象深刻,但我无法提出更好的解决方案。

该方法与找到总和为z的a和b非常相似。

首先对数组排序。 然后将a固定在位置i并检查ii + 1 to n的限制是否为za

由于您有O(n)算法来检查ab是否存在和z 我们仅将其扩展为修正a,然后检查是否可以使用其他两个变量来产生总和。 总运行时间为O(n^2)

这里

 // returns true if there is triplet with sum equal // to 'sum' present in A[]. Also, prints the triplet bool find3Numbers(int A[], int arr_size, int sum) { int l, r; /* Sort the elements */ sort(A, A+arr_size); /* Now fix the first element one by one and find the other two elements */ for (int i=0; i<arr_size-2; i++) { // To find the other two elements, start two index // variables from two corners of the array and move // them toward each other l = i + 1; // index of the first element in the // remaining elements r = arr_size-1; // index of the last element while (l < r) { if( A[i] + A[l] + A[r] == sum) { printf("Triplet is %d, %d, %d", A[i], A[l], A[r]); return true; } else if (A[i] + A[l] + A[r] < sum) l++; else // A[i] + A[l] + A[r] > sum r--; } } // If we reach here, then no triplet was found return false; } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM