python 数据结构与算法之‘变位词’的判断(四种方法分析时间复杂度)
变位词介绍
两词存在组成字母重新排序的关系:
例如:
heart 和 earth apple和pleap
方法一
将两字符串存储到两列表,排序,比较两列表:
def anagramSolution(s1, s2):
if len(s1) != len(s2):
return False
else:
alist1 = list(s1)
alist2 = list(s2)
alist1.sort()
alist2.sort()
if alist1== alist1:
return True
else:
return False
print(anagramSolution('abbcd', 'babdc'))
时间复杂度取决于排序方法sort()(冒泡,希尔,选择,堆排序等等)
较好的为O(log2N)
方法二
将s2存储到列表,将s1每个字符与列表中每个元素比较,如果找到则打勾设为None(因为存在重复)
def anagramSolution1(s1, s2):
if len(s1) != len(s2):
return False
else:
alist = list(s2)# s2复制到列表
pos1 = 0
stillOK = True
while pos1 < len(s1) and stillOK:# 循环s1每个字符
pos2 = 0
found = False
while pos2 < len(alist) and not found:# 循环s2每个字符
if s1[pos1] == alist[pos2]:
found = True
else:
pos2 += 1
if found:
alist[pos2] = None # 找到打钩
else:
stillOK = False
pos1 += 1
return stillOK
print(anagramSolution1('abcd', 'dabc'))
时间复杂度为O(n^2)
方法三
计数法:统计两个词每个字母出现个数,判断是否相同
方便起见:假设都是小写字母,如果不是将计数列表设置更大即可
def anagramSolution3(s1, s2):
c1 = [0]*26
c2 = [0]*26
for i in range(len(s1)):
count = ord(s1[i])-ord('a')
c1[count] += 1
for i in range(len(s2)):
count = ord(s2[i]) - ord('a')
c2[count] += 1
match = True
j = 0
while j<26 and match:
if c1[j] == c2[j]:
j += 1
else:
match = False
return match
print(anagramSolution3('apple', 'pleap'))
时间复杂度最优 O(n),不过要牺牲存储空间为代价
方法四:字典改良方法三
思路同方法三,不过运用了字典更方便,字符串可以包含大小写字母数字等
def anagramSolution4(s1, s2):
d1 = {}
d2 = {}
for x in s1:
if not x in d1:
d1[x] = 1
else:
d1[x] += 1
for x in s2:
if not x in d2:
d2[x] = 1
else:
d2[x] += 1
if d1 == d2:
return True
else:
return False
print(anagramSolution4('aacb1d', 'a1adcb'))
时间复杂度同方法三