三和算法的时间复杂度是多少
Posted
技术标签:
【中文标题】三和算法的时间复杂度是多少【英文标题】:what is the time complexity of the three sum algorithm 【发布时间】:2019-10-04 09:35:35 【问题描述】:它是一个在数组中找到三个和等于零的数字的函数。
//helper function
bool isPresent(int*arr, int size, int index, int num)
for (int i = index; i < size; i++)
if (arr[i] == num)
return true;
return false;
bool threesum(int*arr,int size)
int i = 0, j = 1;
int sum = arr[i] + arr[j];
while (i < size-2)
if (isPresent(arr, size, j + 1, -sum) == true)
cout << arr[i] << " + " << arr[j] << " + " << -sum << '\n';
return true;
if (j == size)
i++;
j = i + 1;
j++;
sum = arr[i] + arr[j];
return false;
threeSum 函数中有两个循环,一个是 while 达到数组的大小 第二个是isPresent,它的时间复杂度是O(n),所以threesum函数的时间复杂度应该是O(n^2),但是while循环因为j而迭代更多的时间,所以threesum函数的时间复杂度是O(n^ 2) 还是 O(n^3)?
【问题讨论】:
这不是回答问题,因此是评论:请注意,这实际上可以在 O(n^2) 平均情况或 O(n^2logn) 最坏情况下完成 - 首先添加所有元素到一个集合,然后检查所有对(您的i
,j
),而不是从头开始检查每个数组 - 只需在这个集合中有效地检查。 (特别注意不要两次使用同一个元素,只需检查找到的元素是否是对中的元素之一即可。
【参考方案1】:
是 O(n^3)。想想 i 是如何随着 j 改变的。假设,n = 10。起初 i = 0,j = 1。直到 j = 10,我才会变成 1,然后在这些步骤之后,再次 i = 1,j = 2。就像写两个 for 循环一样这个:
for(int i = 0; i < n; i++)
for(int j = i+1; j < n; j++)
【讨论】:
他对 3SUM 的解是 O(N³),但一般来说 3SUM 可以低至 O(N²)。 是的,我自己使用哈希表解决了这个问题。我解释了他的代码的复杂性【参考方案2】:简单的方法是 O(N³)。
要查看三个的总和为 0,计算所有总和,并且有 N * (N-1) * (N-2) / 4 个不同的总和。
但是您可以通过首先索引数字然后计算所有对的总和,将它们存储在哈希表中,然后查找总和的负数是否存在并测试其组件是否已经存在,从而轻松改进该界限用于计算总和。这给出了 O(N²)。
https://en.wikipedia.org/wiki/3SUM
bool threesum(const vector<int>& numbers)
std::unordered_map<int,size_t> index;
for (size_t i=0;i!=numbers.size();++i)
index.insert(numbers[i],i);
for (size_t i=0;i!=numbers.size();++i)
for (size_t j=i+1;j!=numbers.size();++j)
const int n = -(numbers[i]+numbers[j]);
if (index.count(n))
if (index[n]==i) continue;
if (index[n]==j) continue;
return true;
return false;
【讨论】:
以上是关于三和算法的时间复杂度是多少的主要内容,如果未能解决你的问题,请参考以下文章