常见的大O计数法
对于下列代码片
赋值操作的数量是4项之和:
T
(
n
)
=
3
+
3
n
2
+
2
n
+
1
T(n)=3+3n^2+2n+1
T(n)=3+3n2+2n+1。第1项是常数3,对应起始部分的3条赋值语句。第2项是
3
n
2
3n^2
3n2,因为有3条语句要在嵌套循环中重复
n
2
n^2
n2次。第3项是
2
n
2n
2n,因为两条语句要循环
n
n
n遍。第4项是常数1,代表最后那条赋值语句。
T
(
n
)
=
3
+
3
n
2
+
2
n
+
1
=
3
n
2
+
2
n
+
4
T(n)=3+3n^2+2n+1=3n^2+2n+4
T(n)=3+3n2+2n+1=3n2+2n+4很容易看出来,
n
2
n^2
n2起主导作用,所以这段代码的时间复杂度是
O
(
n
2
)
O(n^2)
O(n2)。当
n
n
n变大时,其他项以及主导项的系数都可以忽略。
对于下列代码片
分析这个算法。注意,对于
s
1
s1
s1中的
n
n
n个字符,检查每一个时都要遍历
s
2
s2
s2中的
n
n
n个字符。要匹配
s
1
s1
s1中的一个字符,列表中的
n
n
n个位置都要被访问一次。因此,访问次数就成了从1到
n
n
n的整数之和。这可以用以下公式来表示。
∑
i
=
1
n
=
n
(
n
+
1
)
2
=
n
2
2
+
n
2
\sum_{i=1}^{n}=\frac{n(n+1)}{2}=\frac{n^2}{2}+\frac{n}{2}
i=1∑n=2n(n+1)=2n2+2n
当n变大时,起决定性作用的是
n
2
n^2
n2,而
1
2
\frac{1}{2}
21可以忽略。所以,这个方案的时间复杂度是
O
(
n
2
)
O(n^2)
O(n2)。
尽管s1与s2是不同的字符串,但只要由相同的字符构成,它们就是异序词。基于这一点,可以采用另一个方案。如果按照字母表顺序给字符排序,异序词得到的结果将是同一个字符串。下图代码给出了这个方案的实现代码。在Python中,可以先将字符串转换为列表,然后使用内建的sort方法对列表排序。
乍看之下,你可能会认为这个算法的时间复杂度是
O
(
n
)
O(n)
O(n),因为在排序之后只需要遍历一次就可以比较
n
n
n个字符。但是,调用两次sort方法不是没有代价。我们在后面会看到,排序的时间复杂度基本上是
O
(
n
2
)
O(n^2)
O(n2)或
O
(
n
l
o
g
n
O(nlogn
O(nlogn),所以排序操作起主导作用。也就是说,该算法和排序过程的数量级相同。