假设我有三个向量。
#include <vector>
vector<long> Alpha;
vector<long> Beta;
vector<long> Gamma;
让我们假设我已经用数字填充它们,而且我们知道它们的长度都是一样的。 (我们提前知道这个长度 - 让我们说它是3个。)
我最终想要的是所有总和Alpha[i] + Beta[j] + Gamma[k]
中的最小值,以使i
,j
和k
彼此不相等。< / p>
天真的方法看起来像这样:
#include <climits>
long min = LONG_MAX;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k=0; k < 3; k++) {
if (i != j && i != k && j != k) {
long sum = Alpha[i] + Beta[j] + Gamma[k];
if (sum < min)
min = sum;
}
}
}
}
坦率地说,这段代码感觉不对。是否有更快和/或更优雅的方式 - 跳过冗余迭代的方法?
答案 0 :(得分:2)
算法的计算复杂度为O(N^3)
。您可以使用以下方法保存一小部分:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if ( i == j )
continue;
long sum1 = Alpha[i] + Beta[j];
for (int k=0; k < 3; k++) {
if (i != k && j != k) {
long sum2 = sum1 + Gamma[k];
if (sum2 < min)
min = sum2;
}
}
}
}
然而,算法的复杂性仍为O(N^3)
。
如果没有if ( i == j )
检查,最里面的循环将执行N^2
次。通过该检查,您将能够避免最里面的循环N
次。它将执行N(N-1)
次。支票几乎不值得。
答案 1 :(得分:1)
如果你可以暂时修改输入向量,你可以将使用的值与向量的末尾交换,然后迭代向量的开头:
for (int i = 0; i < size; i++) {
std::swap(Beta[i],Beta[size-1]); // swap the used index with the last index
std::swap(Gamma[i],Gamma[size-1]);
for (int j = 0; j < size-1; j++) { // don't try the last index
std::swap(Gamma[j],Gamma[size-2]); // swap j with the 2nd-to-last index
for (int k=0; k < size-2; k++) { // don't try the 2 last indices
long sum = Alpha[i] + Beta[j] + Gamma[k];
if (sum < min) {
min = sum;
}
}
std::swap(Gamma[j],Gamma[size-2]); // restore values
}
std::swap(Beta[i],Beta[size-1]); // restore values
std::swap(Gamma[i],Gamma[size-1]);
}