我有点困惑(登录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吗?如果是这样,为什么。
答案 0 :(得分:2)
1. for (int i = 0; i < (n * .8); i++)
在第一种情况下,基本上可以将0.8n替换为另一个变量,我们将其称为m。
for (int i = 0; i < m; i++)
您循环了m次。您在每次迭代中将i
的值增加一个单位。由于m
和n
只是变量名,因此上述循环的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:
是的,您仅执行chars.length/2
个循环迭代,但是如果s
的长度加倍,则迭代次数也会加倍。这就是线性时间复杂度
类似于前一种情况,您执行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)
其中constant
是1/log(a, base=b)