题目背景
异序词:如果一个字符串只是重排了另一个字符串的字符,那么这个字符就是另一个的异序词。
问题:判断字符串s1与s2是不是异序词?
方案1:清点法
# 实现字符清点
def anagram_solution_1(s1, s2):
still_ok = True
"""
1.检查两个字符串的长度
--如果两个字符长度不等,那一定不是异序词--
"""
if len(s1) != len(s2):
still_ok = False
"""
2.检查第1个字符串中的每个字符是否都出现在第2个字符串中
--如果每一个都对得上,那两个字符串肯定是异序词--
"""
a_list = list(s2)
pos_1 = 0
while pos_1 < len(a_list) and still_ok: # 条件1
pos_2 = 0 # 每次外部循环结束都会再初始化为0,从a_list初字符查找
found = False
while pos_2 < len(a_list) and not found: # 条件2
if s1[pos_1] == a_list[pos_2]: # 条件3:找对应的字符
found = True
else: # 条件4
pos_2 += 1
if found: # 条件5:找到对应字符就替换为None
a_list[pos_2] = None
else: # 条件6
still_ok = False
pos_1 += pos_1
return still_ok
假设s1 = 'pyt',s2 = ‘typ',此时a_list=['t','y','p'],len(a_list)=3,while循环过程各变量变化用表格展示便于理解:
变量的值 | 第一次循环 | 第二次循环 | 第三次循环 |
语句执行情况 | 条件1✅ 条件2✅:条件4➡️条件4➡️条件3 条件5✅ | 条件1✅ 条件2✅:条件4➡️条件3 条件5✅ | 条件1✅ 条件2✅:条件3 条件5✅ |
pos_2(因每次都会初始化,此处只记录内部循环里的值) | pos_2=2 | pos_2=1 | pos_2=0 |
a_list | a_list=['t','y',None] | a_list=['t',None,None] | a_list=[None,None,None] |
pos_1=0 | pos_1=1 | pos_1=2 | pos_1=3 |
still_ok=True | still_ok=True | still_ok=True | still_ok=True |
方案2:排序比较法
# 排序比较法
def anagram_solution_2(s1, s2):
matches = True
"""如果两个字符串相同,则不是异序词"""
if s1 == s2:
matches = False
a_list_1 = list(s1)
a_list_2 = list(s2)
"""对两个字符串列表进行字母排序"""
a_list_1.sort()
a_list_2.sort()
pos = 0
while pos < len(s1) and matches:
if a_list_1[pos] == a_list_2[pos]: # 对两个字符串的相同位置的字符进行比较
pos += 1
else:
matches = False
return matches
方案3:暴力法
穷尽所有可能,将s1中的字符生成所有可能的字符,看s2是否在其中。
~时间复杂度较高,不推荐,此处也不详细解释了
方案4:计数比较法
# 计数比较法
def anagram_solution_4(s1, s2):
c1 = [0] * 26
c2 = [0] * 26
for i in range(len(s1)):
pos = ord(s1[i]) - ord('a')
c1[pos] = c1[pos] + 1
for i in range(len(s2)):
pos = ord(s2[i]) - ord('a')
c2[pos] += 1
j = 0
still_ok = True
while j < 26 and still_ok:
if c1[j] == c2[j]:
j += 1
else:
still_ok = False
return still_ok
可以思考一下时间复杂度分别是多少~就知道哪种方法相对更好了~