變位詞指的是一個單詞能夠經過改變其餘單詞中字母的順序來獲得,也叫作兄弟單詞,如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