更好地了解(log n)时间复杂度

时间:2019-01-14 22:46:26

标签: algorithm performance time-complexity big-o

我有点困惑(登录n)。有了这段代码

public static boolean IsPalindrome(String s) {
    char[] chars = s.toCharArray();
    for (int i = 0; i < (chars.length / 2); i++) {
        if (chars[i] != chars[(chars.length - i - 1)])
            return false;
        }
        return true;
    }
}

我循环n / 2次。因此,随着n的长度增加,我的时间增加了n的一半。我认为这正是log n是什么?但是编写此代码的人说这仍然是O(N)。

在什么情况下循环,事情可以是(log n)吗?例如此代码:

1. for (int i = 0; i < (n * .8); i++)

这是日志n吗?我要循环播放n长度的80%。

这个呢?

2. for (int i = 1; i < n; i += (i * 1.2))

是n吗?如果是这样,为什么。

2 个答案:

答案 0 :(得分:2)

1. for (int i = 0; i < (n * .8); i++) 在第一种情况下,基本上可以将0.8n替换为另一个变量,我们将其称为m。

for (int i = 0; i < m; i++)您循环了m次。您在每次迭代中将i的值增加一个单位。由于mn只是变量名,因此上述循环的Big-O复杂度为O(n)。

2. for (int i = 0; i < n; i += (i * 1.2)) 在第二种情况下,您无需增加i的值,i的值将始终为0。这是无限循环的经典案例。

您要寻找的是2. for (int i = 1; i <= n; i += (i * 1.2)),在这里,您正在对数地递增i的值(但不以2为底)。

考虑for (int i = 1; i <= n; i += i),i的值在每次迭代后都会加倍。 i的值将为1, 2, 4, 8, 16, 32, 64..假设n值为64,您的循环将终止7次迭代,即(log(64) to the base 2) + 1+1,因为我们从1开始循环)操作次数。因此,它成为对数运算。

2. for (int i = 1; i <= n; i += (i * 1.2))在您的情况下,解决方案也是对数解决方案,但不是以2为底。对数运算的基础是2.2,但是用big-O表示法可以沸腾下降到O(log(n))

答案 1 :(得分:0)

我认为您错过了time complexity是什么,以及big O notation是如何工作的。

Big O表示法用于将算法的 渐近 行为描述为问题增长的大小(至无穷大)。特定系数无关紧要。

根据直觉,如果将n增加2倍,则所需执行的步骤数也增加了2倍,这是线性的时间复杂度或所谓的O(n)

让我们回到示例1和2:

  1. 是的,您仅执行chars.length/2个循环迭代,但是如果s的长度加倍,则迭代次数也会加倍。这就是线性时间复杂度

  2. 类似于前一种情况,您执行0.8*n迭代,但是如果n被加倍,则您进行两倍的迭代。同样,这是线性的

最后一个例子是不同的。系数1.2并不重要。重要的是您将i添加到其自身。让我们重新编写该语句

i += (i * 1.2)

相同
i = i + (i * 1.2)

相同
i = 2.2 * i

现在,您清楚地看到,每次迭代都比i多一倍。因此,如果您将n加倍,则只需再进行一次迭代(甚至相同的迭代)。这是基本上亚线性时间复杂度的标志。是的,这是O(log(n))的示例,因为对于大的n,您只需要进行log(n, base=2.2)次迭代,这确实是

 log(n, base=a) = log(n, base=b) / log(n, base=b) = constant * log(x, base=b) 

其中constant1/log(a, base=b)