我正在看《破解编码面试》第6版第49页,示例8。
假设我们有一个算法,它接收一个字符串数组,对每个字符串进行排序,然后对整个数组进行排序。运行时间是什么?
如果最长字符串的长度为s
,而数组的长度为a
,则书中说对每个字符串进行排序将是:
O(a*s log s)
我了解的是,在这种情况下,复杂度取决于上限,所以应该是:
O(s log s)
例如,如果s
是最长字符串的长度,而s1
,s2
,s3
是其他字符串的长度,则复杂度将是:
O(s log s + s1 log s1 + s2 log s2 + s3 log s3)
最终是:
O(s log s)
因为s
的值最高。如果与a
相乘,为什么还要相乘?
答案 0 :(得分:4)
只有在数量较小的情况下,您才可以忽略它们。
忽略较小项的能力实际上是基于您可以忽略常数因子的事实,但这仅在您具有恒定数量的较小项时起作用(否则,常数因数就不会恒定)。
直观地:
如果您有50000000000个长度为10的字符串怎么办? 10 log 10
的某些预定义因子在运行时听起来不正确,您需要在其中放置50000000000。
数学上:
假设您有f(n) + g(n)
,并且g(n)
小于f(n)
,因为n
趋于无穷大。
您可以这样说:
f(n) <= f(n) + g(n) <= f(n) + f(n) = 2.f(n) (as n tends to infinity)
现在您已经取消了g(n)
,并且1
的{{1}}和2
之间只有一个常数,您可以使用渐进符号将其忽略,因此复杂性就是f(n)
。
如果术语的数量为O(f(n))
,则将有a
,并且您不能忽略该a.f(n)
。
a
的证明(至少一种证明方式)涉及选择一个常量a.f(n) = O(f(n))
,使得M
从|a.f(n)| <= M.f(n)
的某个值开始。无论您选择n
的哪个值,总会存在一个较大的M
(仅a
会起作用),因此该证明失败。
答案 1 :(得分:2)
正如Dukeling指出的,a
和s
都是此处的参数。
因此,算法的运行时间取决于两者。没有有关两者之间关系的更多信息,您将无法进一步简化。例如,听起来好像没有a < s
。
但是说给你a < s
。那么您可以说,由于您的O(s log s)
排序操作需要执行a = O(s)
次才能对数组中的所有字符串进行排序,因此总数为O(s^2 log s)
。