字典树-472. 连接词-PYTHON

在这里插入图片描述

锁定长度,逐一遍历法

class Solution(object):
    def findAllConcatenatedWordsInADict(self, words):
        """
        :type words: List[str]
        :rtype: List[str]
        """
        words = sorted(words,key=lambda i:len(i)) #将单词按照长度排序
        s = set(words) #放入集合中,可以去重
        ans = [] 

        while words:
            word = words.pop(-1) #从长度最长的元素开始逐一取出
            s.remove(word) #从集合中去除该单词,因为是从最长的单词开始判断,所以不会存在短单词是由长单词组成的情况。
            L = len(word)
            stack = [0]
            while stack:
                p = stack.pop(0) #取出栈中第一项
                flag = False
                for i in range(p+1,L+1):#限制字符长度不可超过取出的单词长度会产生溢出
                    if word[p:i] in s: #遍历不同长度的单词是否存在在集合中
                        stack.append(i) #将下一个单词判断的开始位置放入栈中
                        if i == L: #如果取完存在单词后右侧下标恰好为所判断单词总长度那么就代表该单词是一个连接词
                            ans.append(word)
                            flag = True #找到一个连接词,跳出两层循环,继续判断下一个词
                            break
                if flag:
                    break
        return ans

建立前缀树进行单词前缀逐一比对的方法

class Solution(object):
    def findAllConcatenatedWordsInADict(self, words):
        """
        :type words: List[str]
        :rtype: List[str]
        """
        def check_word(word,pre_dict):
            if len(word) == 0: #因为是递归调用,用于结束递归,结束的条件是单词正好是连接词,然后从单词长度加一的位置调用函数自身时,传入的字符串为None,所以长度为0,仅有这一种情况会使得单词长度变为0
                return True
            cur_dict = pre_dict
            for index,c in enumerate(word):
                cur_dict = cur_dict.get(c,None) #取字母元素,取不到的话默认返回None
                if cur_dict is None:  #没有与当前所取字母元素对应的字典树,即匹配失败
                    return False
                if cur_dict.get("end",0) == 1:#如果取到的是结束符那么代表当前存在单词匹配结束,有可能为连接词,继续向后判断是否为已经存在的单词
                    if check_word(word[index+1:],pre_dict):# 递归调用函数判断发现单词的下一个位置到单词结束
                        return True
            return False

        words.sort(key = lambda x:len(x)) #单词按长度排列 [u'cat', u'dog', u'rat', u'cats', u'dogcatsdog', u'catsdogcats', u'ratcatdogcat', u'hippopotamuses']
        ans = list()
        pre_dict = dict() #前缀字典
        for item in words: #遍历单词,此处有讲究,从短的开始进行比对,首先建立短单词的前缀树,用于组成长单词,不会存在短单词由长单词组成的情况。
            if len(item) == 0:
                continue
            if check_word(item,pre_dict):#检查是否为连接词
                ans.append(item)
            else:
                cur_dict = pre_dict
                for c in item:
                    if cur_dict.get(c,None) is None:#检查是否存在前缀树
                        cur_dict[c] = dict() #建立键值并添加新的子字典
                    cur_dict = cur_dict.get(c) #转移跟踪指针到子字典树中,用于添加下一个元素到字典树中
                cur_dict["end"] = 1 #添加单词结尾标志
        return ans    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值