zoukankan      html  css  js  c++  java
  • 算法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

      

  • 相关阅读:
    chrome调试工具常用功能整理(转)
    js事件的相关收集
    键盘事件之keydown keypress keyup区别
    性能监控系统的搭建(转)
    关于浏览器并发请求数的研究及优化
    http头部信息研究
    什么是HTTP Keep-Alive呢?
    JavaScript跨域深入研究与解决办法(转)
    LRU Cache
    字节对齐&&sizeof
  • 原文地址:https://www.cnblogs.com/Lee-yl/p/8847988.html
Copyright © 2011-2022 走看看