计算向量的笛卡尔乘积的这个函数的时间/空间复杂度是多少?

时间:2018-02-28 00:58:00

标签: time-complexity complexity-theory asymptotic-complexity space-complexity

我无法弄清楚这个功能的时间和空间复杂性。

vector<vector<string>> stringCombinations(const vector<vector<string>> &values) {
    vector<vector<string>> results = {{}};

    for(const auto &vec: values) {
        vector<vector<string>> temp;

        for(const auto &r: results) {
            for(const auto &s: vec) {
                temp.push_back(r);
                temp.back().push_back(s);
            }
        }

        results = move(temp);
    }

    for(const auto &row: results) {
        for(const auto &s: row) {
            cout << s << " ";
        }
        cout << endl;
    }

    return results;
}

此函数只是字符串的笛卡尔积。给定字符串向量的向量,它会打印并返回这些字符串的所有组合。

当看到3个嵌套循环时,我立即认为它在时间复杂度方面大致在 O(n 3 的范围内。但是,当函数继续运行时,第二个循环的长度会发生变化。在第一次迭代时,向量中只有一个元素是空向量。在第二次迭代中,它包含长度为1的n个向量,其中n是第一个字符串向量的长度。所以我真的不确定这会对事情产生什么影响。

至于空间复杂性,由于用于存储结果的2D矢量,我认为它位于 O(m * n)附近。我不确定mn到底在哪里。

1 个答案:

答案 0 :(得分:1)

计算长度为stringCombinations()的{​​{1}}向量的笛卡尔积的n函数的复杂度为 O(n * k ^ n)。< / p>

k成为函数v的参数,让 n 表示stringCombinations()。让 v1 ... vn 表示v.size()的元素,让| u |表示向量 u 中的元素数。

该函数计算 n 向量 v1 ... vn 的笛卡尔积。结果向量v的大小为| v1 | * | v2 | * .... * | vn |。 results的每个元素都是大小为 n 的向量。设 k 表示max(| v1 |,...,| vn |)。

现在我们可以估计算法的复杂性。设 f(i)表示第一循环的 i 次迭代中第二循环的迭代次数。然后我们将得到O( n * f(n) * k ),因为 k 是上层限制了第三个循环的迭代次数。

对于 f(n),我们有以下公式。如果 ki vi 中的字符串数,那么 f(i) = f(i-1) * K(I-1)。当f(1)= 1时,很容易看出 f(n) = 1 * k1 * ... * k(n-1) = O( k ^(n-1))。然后主循环的复杂性受O( n * k ^ n )的限制。

更新于13.03.2018 让我们在此处详细了解(并澄清符号并修复流程中的一些错误)。在第一个循环的每次迭代中,第二个循环越过results向量。在第一次迭代中,它包含1个元素results。在第二次迭代中,{}的大小等于我们用 k1 表示的第一个元素results的大小。在使用values的第二次迭代中,每个元素vec = {s1,s2,...}将替换为 k2 元素。 r={s}{s,s1},...因此,第二次迭代后{s,s2}向量的大小将等于 k1 * k2 。在每次后续迭代 i 之后,result的大小将乘以 ki 。此大小将确定第一个循环的下一次迭代中第二个循环的迭代次数。所以* f(i + 1)= 1 * k1 * ... * ki

一个例子很方便。让result。这里 n = 2.在第一次迭代开始时我们有

values = {{"1","2"},{"3","4","5"}}

在第二次迭代开始时我们有

   results = {{}}, vec={"1","2"}, *k1* = 2, *f(1)*=1

最后我们有

   results = {{"1"},{"2"}}, vec={"3","4","5"}, *k2*=3, *f(2)*=2

操作次数为 T = f(1) * k1 + f(2) * k2 。当 k = max( k1 k2 )= 3时,我们有 T &lt; = 3 *(< em> f(1) + f(2))&lt; = 3 * f(2) * 2。 更新结束

另请注意, results = {{"1","3"},{"1","4"},{"1","5"}, {"2","3"},{"2","4"},{"2","5"}} 中的元素数量受O( n * k ^ n )的限制,因此这也是第二个循环。

正如您所说,如果我们让 m = k ^ n ,那么复杂性就是O( m * n )。然而,这种表示法可能会产生误导,因为输入数组可以被 k 数组视为 n ,因此最好根据输入的维数进行复杂性估计。数组,所以它是O( n * k ^ n )。