变位词指的是一个单词能够经过改变其余单词中字母的顺序来获得,也叫作兄弟单词,如army->mary。python
经典的字符串变位词检测问题是比较不一样数量级函数算法的一个典型例子。若是一个字符串是 另外一个字符串的从新排列组合,那么这两个字符串互为变位词。好比,”heart”与”earth”互为变位 词,”python”与”typhon”也互为变位词。为了简化问题,咱们设定问题中的字符串长度相同,都是由 26 个小写字母组成。咱们须要编写一个接受两个字符串,返回真假,表明是不是一对变位词的布尔 函数。算法
法①:检查标记【时间复杂度为O(n2)】函数
思路:检查第一个字符串中的全部字符是否是都在第二个字符串中出现。 若是可以把每个字符都“检查标记”一遍,那么这两个字符串就互为变位词。检查标记一个字符 要用特定值 None 来代替,做为标记。然而,因为字符串不可变,首先要把第二个字符串转化成一个列表。第一个字符串中的每个字符均可以在列表的字符中去检查,若是找到,就用 None 代替以示标记。spa
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)】code
思路:尽管 s1 和 s2 并不相同,但若为变位词它们必定包含彻底同样的字符,利用这一特色,咱们能够 采用另外一种方法。咱们首先从 a 到 z 给每个字符串按字母顺序进行排序,若是它们是变位词,那么 咱们将获得两个彻底同样的字符串。此外,咱们能够先将字符串转化为列表,再利用 Python 中内建
的 sort 方法对列表进行排序。下面代码展现了这种方法。
第一眼看上去你可能会认为这个算法的复杂度是 O(n),毕竟排序后只须要一个简单的循环去比较 n 个字符。然而对 Python 内建的 sort 方法的两次使用并不是毫无消耗。事实上,正如咱们在后面的章节 中将要看到的,排序方法的复杂度每每都是 O(n²)或者 O(n㏒n),因此排序贡献了这个函数主要的循 环操做。最终,这个算法和排序的复杂度相同。blog
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