# 异位词的判断
# 异位词: abc与cba cat与tca 即一方的字母可以由另一方字母改变排列顺序得到
# 最简单的实现思路:
# 暴力查找,直接将一方全体字符依次与另一方全体对比,如果全部成立,则判定为真
# 注意事项: 1.两词的长度不一致时直接判定为假
# 2.查找对比成功时要注意字符的下标值,例如aaa和abc,aaa中的(任意字符 in abc)都
# 会获得True的结果,但aaa和abc并不是一对异位词。
# 解法2:将两个字符串进行排序, 排序完成后比较是否相同即可
import typing
# 测试用例
s = 'abc', 'age', 'meme', 'snake'
ss = 'cba', 'ega', 'emme', 'aaken'
# 英语不好,实在不知道异位词该怎么翻译...
def reverse_word(s0:str, s1:str)->bool:
l0, l1 = len(s0), len(s1)
# 预先处理特殊情况,当两个字符串长度不一致时直接返回False
if l0 != l1:
return False
# 解法1: 时间复杂度: O(n^2)
# for a in s0:
# i = s1.find(a)
# if i == -1:
# return False
# s1 = s1[:i] + s1[i + 1:]
# return True
# 解法2:时间复杂度:O(nlog n)
# return sorted(s0) == sorted(s1)
# 这里隆重介绍解法3: 参考一位美国程序员的实现思路
# 异位词中只会存在小写的英文字母,这是一个大前提(当然,全部的ASCII字符也可)
# 为每一个字母设定一个质数值,分别求出两个字符串各成员的质数值的乘积
# 若乘积相同,则说明两个字符串互为异位词
# 时间复杂度:O(n)
# 不得不说,这种思路是真的棒......
# 这个映射表应放在函数外,作为全局变量使用,避免重复创建浪费时间。
# 为方便演示,故放在此处。 PrimeIter见函数下方代码
map_ = {chr(k):v for k, v in zip(range(97, 123), PrimeIter(26))}
v0 = v1 = 1
for a, b in zip(s0, s1):
v0 *= map_[a]
v1 *= map_[b]
return v0 == v1
# 质数迭代器
class PrimeIter(typing.Iterable):
def __init__(self, amount:int=1):
self.amount = amount
def __iter__(self):
yield 2
n = 3
count = 1
while count < self.amount:
if self.__is_prime(n):
yield n
count += 1
n += 2
def __is_prime(self, n:int)->bool:
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
# 测试
for a, b in zip(s, ss):
print(reverse_word(a, b))
异位词算法(巧用质数性质)
于 2022-04-18 15:15:54 首次发布