二、算法分析
程序和算法的区别:
算法是对问题的解决的分步描述,程序是采用某种编程语言实现的算法。
算法分析概念:
比较程序好坏:
代码风格、执行效率等(python代码有很强的可读性,代码风格统一)
算法分析方法:
运行时间检测分析(不可靠)
运行时间检测可以用python的time模块(运行时间检测分析有问题,因为编程语言和运行环境时间都会有影响)
衡量计算内存可以评判
算法时间度量指标:
问题规模影响算法执行时间
大O表示法
大O表示法:算法的时间复杂度通常用大O符号表述,定义为T[n] = O(f(n))。称函数T(n)以f(n)为界或者称T(n)受限于f(n)。 如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n)。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复杂度”。
算法的目标
容易理解
最小的代价
算法的执行时间
|
1
2
3
4
5
6
7
|
int num1,num2; for(int i=0; i<n; i++){ num1 += 1; for(int j=1; j<=n; j*=2){ num2 += num1; } } |
变位词指的是一个单词可以通过改变其他单词中字母的顺序来得到,也叫做兄弟单词,如army->mary。
例子1:判断两个字符串s1和s2是否为变位词。
经典的字符串变位词检测问题是比较不同数量级函数算法的一个典型例子。如果一个字符串是 另一个字符串的重新排列组合,那么这两个字符串互为变位词。比如,”heart”与”earth”互为变位 词,”python”与”typhon”也互为变位词。为了简化问题,我们设定问题中的字符串长度相同,都是由 26 个小写字母组成。我们需要编写一个接受两个字符串,返回真假,代表是否是一对变位词的布尔 函数。
法①:检查标记【时间复杂度为O(n2)】
思路:检查第一个字符串中的所有字符是不是都在第二个字符串中出现。 如果能够把每一个字符都“检查标记”一遍,那么这两个字符串就互为变位词。检查标记一个字符 要用特定值 None 来代替,作为标记。然而,由于字符串不可变,首先要把第二个字符串转化成一个列表。第一个字符串中的每一个字符都可以在列表的字符中去检查,如果找到,就用 None 代替以示标记。
def anagram(s1,s2):
s2=list(s2)
still_ok=True
i=0
while i<len(s1) and still_ok:
found=False
j=0
while j<len(s2) and not found:
if s1[i]==s2[j]:
Found=True
else:
j+=1
if found:
s2[j]==None
else:
still_ok=False
i+=1
return still_ok
法②:排序比较【时间复杂度为O(n2)】
思路:尽管 s1 和 s2 并不相同,但若为变位词它们一定包含完全一样的字符,利用这一特点,我们可以 采用另一种方法。我们首先从 a 到 z 给每一个字符串按字母顺序进行排序,如果它们是变位词,那么 我们将得到两个完全一样的字符串。此外,我们可以先将字符串转化为列表,再利用 Python 中内建
的 sort 方法对列表进行排序。下面代码展示了这种方法。
第一眼看上去你可能会认为这个算法的复杂度是 O(n),毕竟排序后只需要一个简单的循环去比较 n 个字符。然而对 Python 内建的 sort 方法的两次使用并非毫无消耗。事实上,正如我们在后面的章节 中将要看到的,排序方法的复杂度往往都是 O(n²)或者 O(n㏒n),所以排序贡献了这个函数主要的循 环操作。最终,这个算法和排序的复杂度相同。
def anagram(s1,s2):
s2=list(s2)
s1=list(s1)
list_s1=sorted(s1)
list_s2=sorted(s2)
still_ok=True
i=0
while i<len(list_s1):
if list_s1[i]==list_s2[i]:
still_ok=True
else:
still_ok=False
i+=1
return still_ok
法③:计数比较法【时间复杂度O(n)】
解决变位词问题的最后一个方法利用了任何变位词都有相同数量的 a,相同数量的 b,相同数量 的 c 等等。为判断两个字符串是否为变位词,我们首先计算每一个字符在字符串中出现的次数。由于
共有 26 个可能的字符,我们可以利用有 26 个计数器的列表,每个计数器对应一个字符。每当我们 看到一个字符,就在相对应的计数器上加一。最终,如果这两个计数器列表相同,则这两个字符串 是变位词。下面展示了这种方法:
def anagram(s1,s2):
counter1=[0]*26
counter2=[0]*26
for i in s1:
counter1[ord(i)-ord('a')]+=1
for i in s2:
counter2[ord(i)-ord('a')]+=1
if counter1==counter2:
return True
else:
return False
算法优化法则:


例子:






![]()



字典






浙公网安备 33010602011771号