使用两个循环进行更改的时间复杂度 - javascript

时间:2015-11-27 19:30:05

标签: javascript algorithm

以下函数的时间复杂度是多少,它返回给定硬币的值和面额(即镍,角钱等)可以改变的方式的数量?我的答案是它是o(n),因为第二个循环基本上“缓存”你正在寻找的值,为了清晰起见,你可以在没有它的情况下编写这个函数。但是,当我看到两个for循环时,我总是倾向于认为o(n ^ 2)。变量j不是像临时变量那样独立于'i'运行吗?

var makeChange = function (value, denoms) {
  var changeCounts = { 0: 1};

  for (var i = 0; i < denoms.length; i++) {
    for (var j = denoms[i]; j <= value; j++) {
      var remainder = j - denoms[i];
      if (changeCounts[j]) {
        changeCounts[j] += changeCounts[remainder];
      } else {
        changeCounts[j] = changeCounts[remainder];
      }
    }
  }

  return changeCounts[value];
}

2 个答案:

答案 0 :(得分:0)

我无法弄清楚你通过这个代码究竟想要做什么,但是使用Big O表示法时你总是考虑最坏的情况,在这种情况下,两个循环都会执行最多次,因此o(n ^ 2)。如果某些东西被缓存并且你可以跳过循环那么为什么你需要那个循环呢?但对于您发布的代码,时间复杂度为o(n ^ 2)。

答案 1 :(得分:0)

让我们将问题陈述框架为:

给定值N,如果我们想要改变N美分,并且我们每个S = {S1,S2,..,Sm}值的硬币都有无限供应,我们可以通过多少方式进行更改?硬币的顺序无关紧要。

例如,对于N = 4和S = {1,2,3},有四个解:{1,1,1,1},{1,1,2},{2,2}, {1,3}。因此输出应为4.对于N = 10且S = {2,5,3,6},有五种解决方案:{2,2,2,2,2},{2,2,3,3}, {2,2,6},{2,3,5}和{5,5}。所以输出应该是5。

在您的代码中,在外部循环中,您将遍历所有面额(0

在i = 0时外循环的第一次迭代中,内循环将从1迭代到1000。 当i = 1时,你的外部循环将从2迭代到1000.类似于内部循环的第i次迭代,你的外部循环将从i + 1迭代到1000.

所以我们迭代1000 + 999 + 998 + 997 + 996 = 4990次,几乎等于5000,基本上是N x M.

在计算算法复杂度时,我们总是要考虑最坏情况。因此,解决方案的时间复杂度为O(mn),其中n是总变化,m是可用的面额数。