算法2----------变位词

1、背景:

  变位词指的是一个单词可以通过改变其他单词中字母的顺序来得到,也叫做兄弟单词,如army->mary。

题1:判断两个字符串s1和s2是否为变位词。

  经典的字符串变位词检测问题是比较不同数量级函数算法的一个典型例子。如果一个字符串是 另一个字符串的重新排列组合,那么这两个字符串互为变位词。比如,”heart”与”earth”互为变位 词,”python”与”typhon”也互为变位词。为了简化问题,我们设定问题中的字符串长度相同,都是由 26 个小写字母组成。我们需要编写一个接受两个字符串,返回真假,代表是否是一对变位词的布尔 函数。

法①:检查标记【时间复杂度为O(n2)】

  思路:检查第一个字符串中的所有字符是不是都在第二个字符串中出现。 如果能够把每一个字符都“检查标记”一遍,那么这两个字符串就互为变位词。检查标记一个字符 要用特定值 None 来代替,作为标记。然而,由于字符串不可变,首先要把第二个字符串转化成一个列表。第一个字符串中的每一个字符都可以在列表的字符中去检查,如果找到,就用 None 代替以示标记。

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)】

  思路:尽管 s1 和 s2 并不相同,但若为变位词它们一定包含完全一样的字符,利用这一特点,我们可以 采用另一种方法。我们首先从 a 到 z 给每一个字符串按字母顺序进行排序,如果它们是变位词,那么 我们将得到两个完全一样的字符串。此外,我们可以先将字符串转化为列表,再利用 Python 中内建
的 sort 方法对列表进行排序。下面代码展示了这种方法。
第一眼看上去你可能会认为这个算法的复杂度是 O(n),毕竟排序后只需要一个简单的循环去比较 n 个字符。然而对 Python 内建的 sort 方法的两次使用并非毫无消耗。事实上,正如我们在后面的章节 中将要看到的,排序方法的复杂度往往都是 O(n²)或者 O(n㏒n),所以排序贡献了这个函数主要的循 环操作。最终,这个算法和排序的复杂度相同。

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

 

 

 

  

转载于:https://www.cnblogs.com/Lee-yl/p/8847988.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值