【发布时间】:2017-11-09 12:54:06
【问题描述】:
考虑使用类似的东西
StringBuilder sb = new StringBuilder();
for(int i = 0; i < n; i++){
sb.append('a');
}
代码的效率是O(N^2)还是O(N)?
【问题讨论】:
-
您可能想要预先分配容量,例如:
StringBuilder sb = new StringBuilder(n);这对于大多数动态大小的数组或列表都是正确的。如果没有预分配,您将依赖于每个 log(n) 周期或每个 n 周期可能出现的自动重新分配。让你慢到O(n*log(n))甚至O(n^2)。 -
写
StringUtils.repeat('a', n);的路很长,我会这样描述它。 -
@ebyrob,不,自动重新分配不会减慢您超过 O(n) 的速度。最多为 O(n + n/2 + n/4 + ...) = O(2n) = O(n)。
-
@LouisWasserman 在最坏的情况下我期望重新分配在每个循环中都进行
i操作,但我承认我在大 O 表示法上有点弱。那将是 O(n + 1 + 2 + 3 + 4 ... + n) 这将是n * (n+1)/2操作。但是,如果将每个 realloc 的大小加倍,那么你是对的,就像我之前所说的那样,它只会是O(log(n)*log(n))或O(n)而不是O(n*log(n))。我仍然认为在严重依赖数组重新分配时,了解一些有关实现的信息很重要。不同的平台使用不同的生长因子。 en.wikipedia.org/wiki/Dynamic_array
标签: java