LeetCode-单词类题目汇总

30 篇文章 0 订阅

1. 拼写单词

给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。

假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。

注意:每次拼写时,chars 中的每个字母都只能用一次。

返回词汇表 words 中你掌握的所有单词的 长度之和。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-words-that-can-be-formed-by-characters/

    def countCharacters(self, words, chars):
        c_count = collections.Counter(chars)
        result = 0
        for word in words:
            wc_count = collections.Counter(word)
            if all(wc_count[c] <= c_count.get(c, 0) for c in wc_count):
                result += len(word)
        return result

2.单词拆分

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-break

方法一:应用DFS+记忆(超时)

  def wordBreak(self, s, wordDict):
        def dfs(s, word_dict, sets):
            if s in sets:
                return True
            if not s:
                return True
            for i in range(1, len(s)+1):
                word = s[:i]
                if word not in word_dict:
                    continue
                if dfs(s[i:], word_dict, sets):
                    sets.add(s)
                    return True

            return False

        return dfs(s, set(wordDict), set())

方法二:优化,应用Python 缓存机制与 functools.lru_cache
https://blog.csdn.net/qq_19446965/article/details/104070046

def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        import functools
        @functools.lru_cache(None)
        def dfs(s, word_dict):
            if len(s) == 0:
                return True
            for i in range(1, len(s)+1):
                word = s[:i]
                if word not in word_dict:
                    continue
                if dfs(s[i:], word_dict):
                    return True

            return False

        return dfs(s, tuple(wordDict))

3.单词拆分 II

给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-break-ii

方法一:DFS+缓存

  def wordBreak(self, s, wordDict):
        def dfs(s, word_dict, sets):
            if s in sets:
                return sets[s]
            if len(s) == 0:
                return []
            partitions = []
            if s in word_dict:
                partitions.append(s)
            for i in range(1, len(s)):
                word = s[:i]
                if word not in word_dict:
                    continue
                sub_partitions = dfs(s[i:], word_dict, sets)
                partitions.extend(map(lambda sub_partition: word + " " + sub_partition, sub_partitions))
            sets[s] = partitions
            return partitions

        return dfs(s, set(wordDict), {})

方法二:DFS+内部cache缓存

    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        import functools
        @functools.lru_cache(None)
        def dfs(s):
            if len(s) == 0:
                return []
            partitions = []
            if s in wordDict:
                partitions.append(s)

            for i in range(1, len(s)):
                word = s[:i]
                if word not in wordDict:
                    continue
                sub_partitions = dfs(s[i:])
                partitions.extend(map(lambda sub_partition: word + " " + sub_partition, sub_partitions))
            return partitions

        return dfs(s)

4.单词接龙

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:

每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder

方法:BFS+缓存

def ladderLength(self, beginWord, endWord, wordList):
        def get_next_words(word, dict):
            words = []
            for i in range(len(word)):
                for c in 'abcdefghijklmnopqrstuvwxyz':
                    next_word = word[:i] + c + word[i + 1:]
                    if next_word != word and next_word in dict:
                        words.append(next_word)
            return words
        
        if endWord not in wordList:
            return 0
        
        dict = set(wordList)           
        queue = [(beginWord, [beginWord])]
        depth = 0
        distance = set()
        while queue:
            depth += 1
            new_queue = []
            for cur, path in queue:
                if cur == endWord:
                    return depth
                set_path = set(path)
                for next in get_next_words(cur, dict):
                    if next in distance:
                        continue
                    distance.add(next)
                        
                    if next not in set_path: 
                        new_queue.append((next, path + [next]))
                        
            queue = new_queue
        
        return 0

5.单词接龙

给定两个单词(beginWord 和 endWord)和一个字典 wordList,找出所有从 beginWord 到 endWord 的最短转换序列。转换需遵循如下规则:

每次转换只能改变一个字母。
转换过程中的中间单词必须是字典中的单词。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-ladder-ii

方法:BFS+缓存

    def findLadders(self, beginWord, endWord, wordList):
        def get_next_words(word, dict):
            words = []
            for i in range(len(word)):
                for c in 'abcdefghijklmnopqrstuvwxyz':
                    next_word = word[:i] + c + word[i + 1:]
                    if next_word != word and next_word in dict:
                        words.append(next_word)
            return words
        
        if endWord not in wordList:
            return []

        dict = set(wordList)           
        queue = [(beginWord, [beginWord])]
        res = []
        depth = 0
        distance = {}
        min_len = float('inf')
        while queue:
            depth += 1
            new_queue = []
            for cur, path in queue:
                if cur == endWord:
                    res.append(path)
                    continue   
                set_path = set(path)  # 优化,减少遍历时间
                for next in get_next_words(cur, dict):
                    if distance.get(next) and distance.get(next) < depth:
                        continue
                    distance[next] = depth
                    if next not in set_path: 
                        new_queue.append((next, path + [next]))
            if res:
                break      
            queue = new_queue
        
        return res

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值