Python数据结构2:变位词判断,写bool函数判断两个词是否为变位词并分析算法复杂度

题目:

写bool函数判断两个词是不是变位词
变位词: 字母完全相同(大小写也相同),但是顺序不同的词。
如 python , typhon. heart , earth, 为了简单起见,本题假设参与判断的两个词仅由小写
字母构成,而且长度相等,因为长度不等一定不是变位词

1. 解法1:逐个字母比较

遍历第一个词中的每个字母,
逐个在第二个词中找相同的字母,
找到时,将第二个词中此字母设置位None(即图中的对勾)避免重复,
当第二个词全是None时,他们时变位词,否则不是

写法一

def displacement_word(word1, word2):
    word1_list = list(word1)  # 把第一个单词存入列表中
    word2_list = list(word2)
    if len(word1_list) != len(word2_list):  # 长度不同的词一定不是变位词
        return False
    for i in range(len(word1_list)):  # word1 的每个字母, 逐个和 word2 中的每个字母比较
        for j in range(len(word2_list)):
            if word1_list[i] == word2_list[j]:
                word2_list[j] = None  # 如果两个字母相同,就把 word2 里面的变成 None,即打上勾,避免重复比较

    for k in word2_list:
        if k is not None:  # 当 word2_list 中都是None时, 表示word1 一一对应了
            return False
        else:
            return True


print(displacement_word("heart", "earth"))

写法二

def anagramSolution1(word1, word2):
    result = True
    list1 = list(word1) # 变成列表好做对比
    list2 = list(word2)
    if len(word1) != len(word2) or word1 == word2 : # 长度不同 或 两个词完全相同一定不是变位词
        result = False
    else:
        for i in range(len(list1)):
            for j in  range(len(list2)):
                if list1[i] == list2[j]: # 逐个word1的字母 和word2挨个比较
                    list2[j] = None # 相同时,将word2标记为None,避免重复比较
        for i in  range(len(list2)):
            if list2[i] != None: # 是变位词的话 list2种的每个字母都是None
                result = False
            else:
                result = True
    return result
print(anagramSolution1('Python', 'tyPhon'))

问题规模是 n n n个字母,算法复杂度是双重循环那里 O ( n 2 ) O(n^2) O(n2)

2. 解法2 先排序再比较

两个词按照字母顺序排好序,
两个变位词排序后的是完全相同的

def anagramSolution2(word1, word2):
    list1 = list(word1)
    list2 = list(word2)
    list1.sort() # 按字母顺序排序
    list2.sort()
    result = True
    if len(word1) != len(word2) or word1 == word2 : # 长度不同 或 两个词完全相同一定不是变位词
        result = False
    else:
        if list1 != list2: # 变位词再排序后的列表是完全相同的
            result = False
    return result
print(anagramSolution2('abcd', 'acdb'))

sort函数的算法杂度是 O ( n l o g n ) O(nlogn) O(nlogn)

3.解法3:暴力法

穷举所有用第一个单词的字母排列可能出现的所有的单词。
然后看第二个单词是不是其中的一个。
难度在于找到第一个单词所有字母的全排列,全排列的字符串个数是 n ! n! n!个。

注意:阶乘比指数更复杂,即 O ( n ! ) > O ( 2 n ) O(n!) > O(2^n) O(n!)>O(2n)
因此暴力法不好。

4.解法4:计数法

对比两个词中每个字母出现的次数,如果26个字母出现的次数都相同的
话,这两个字符串就一定是变位词

计数完成后,进入比较阶段,看两个字符串的计数器是否相同,如果相同则输出是变位词的结论

def anagramSolution3(word1, word2):
    c1 = [0] * 26
    c2 = [0] * 26
    result = True
    for i in range(len(word1)):
        pos = ord(word1[i]) - ord('a') # ord函数是ASCII
        c1[pos] = c1[pos] + 1
    for i in range(len(word2)):
        pos = ord(word2[i]) - ord('a') # ord函数是ASCII
        c2[pos] = c2[pos] + 1
    if c1 != c2:
        result = False
    return result
print(anagramSolution3('apple', 'pleap'))

算法复杂度 O ( n ) O(n) O(n)

参考文献

本文的知识来源于B站视频 【慕课+课堂实录】数据结构与算法Python版-北京大学-陈斌-字幕校对-【完结!】,是对陈斌老师课程的复习总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值