我从下面的代码中获得了所有独特的三元组,但我希望减少它的时间 复杂。它由三个for循环组成。所以我的问题是:是否有可能在最小数量的循环中减少时间复杂度?
提前致谢。让我知道。
#include <cstdlib>
#include<iostream>
using namespace std;
void Triplet(int[], int, int);
void Triplet(int array[], int n, int sum)
{
// Fix the first element and find other two
for (int i = 0; i < n-2; i++)
{
// Fix the second element and find one
for (int j = i+1; j < n-1; j++)
{
// Fix the third element
for (int k = j+1; k < n; k++)
if (array[i] + array[j] + array[k] == sum)
cout << "Result :\t" << array[i] << " + " << array[j] << " + " << array[k]<<" = " << sum << endl;
}
}
}
int main()
{
int A[] = {-10,-20,30,-5,25,15,-2,12};
int sum = 0;
int arr_size = sizeof(A)/sizeof(A[0]);
cout<<"********************O(N^3) Time Complexity*****************************"<<endl;
Triplet(A,arr_size,sum);
return 0;
}
答案 0 :(得分:1)
我不是算法的秘诀,但是我可以看到让你的程序更好的一种方法是在你的binary search
上third loop
获得一个价值,它可以为你提供总和使用前2个值。但是,这需要您的数据事先sorted
才能使其正常工作(这显然会产生一些开销,具体取决于您的sorting algorithm
(std::sort
的平均时间复杂度为O (n log n)
) )。
如果您想使用并行编程并使程序在多个线程上运行,您可以随时使用,但这可能会非常混乱。
除了这些建议外,很难想出更好的方法。
答案 1 :(得分:0)
如果您首先对列表进行排序,然后对第三个值进行二进制搜索,则可以轻松地获得O(n^2*logn)
稍微更好的复杂度。排序需要O(nlogn)
,而三元组搜索需要O(n^2)
枚举存在时间O(logn)
的所有可能对,以便对总数为O(nlogn + n^2logn)
的thrid值进行二进制搜索或只需O(n^2*logn)
。
可能还有一些其他奇特的东西,你可以做二分搜索来减少它,但我不能轻易地看到(凌晨4点)比这更好。
答案 2 :(得分:0)
当三元组总和为零时,第三个数字完全由两个数字决定。因此,您只能自由选择每个三元组中的两个数字。使用 n 可能的数字,这将产生最大 n 2 三元组。
我怀疑,但我不确定,这是你能做的最好的复杂性。对于随机的有符号整数序列,对于 n 2 的顺序,对于零和三元组的数量是否一定不清楚。如果它更少(不太可能,但如果),则可能做得更好。
无论如何,按照 n 2 的顺序执行此操作的简单方法是首先扫描数字,将它们存储在具有恒定时间的数据结构中lookup(C ++标准库提供了这样的)。然后按照发布的代码扫描数组,不同之处仅在于三元组的第一个和第二个数字。对于第三个数字,在已经建立的恒定时间查找数据结构中查找:如果它在那里,那么你有一个潜在的新三元组,否则不是。
对于如此找到的每个零和三元组,将其置于恒定时间查找结构中。
这确保了唯一性标准,没有额外的复杂性。
答案 3 :(得分:-1)
在最坏的情况下,在大小为n的数组中有C(n, 3)个三元组,其总和为零。 C(n,3)是Θ(n³),打印三元组需要Θ(n³)时间。一般来说,你不能比立方复杂度更好。