异位词算法(巧用质数性质)

# 异位词的判断
# 异位词: 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))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值