leetcode單詞類題目彙總

1. 拼寫單詞

給你一份『詞彙表』(字符串數組) words 和一張『字母表』(字符串) chars。

假如你可以用 chars 中的『字母』(字符)拼寫出 words 中的某個『單詞』(字符串),那麼我們就認爲你掌握了這個單詞。

注意:每次拼寫時,chars 中的每個字母都只能用一次。

返回詞彙表 words 中你掌握的所有單詞的 長度之和。

示例 1:

輸入:words = ["cat","bt","hat","tree"], chars = "atach"
輸出:6
解釋: 
可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6。
示例 2:

輸入:words = ["hello","world","leetcode"], chars = "welldonehoneyr"
輸出:10
解釋:
可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10。

來源:力扣(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 是否可以被空格拆分爲一個或多個在字典中出現的單詞。

說明:

拆分時可以重複使用字典中的單詞。
你可以假設字典中沒有重複的單詞。
示例 1:

輸入: s = "leetcode", wordDict = ["leet", "code"]
輸出: true
解釋: 返回 true 因爲 "leetcode" 可以被拆分成 "leet code"。
示例 2:

輸入: s = "applepenapple", wordDict = ["apple", "pen"]
輸出: true
解釋: 返回 true 因爲 "applepenapple" 可以被拆分成 "apple pen apple"。
     注意你可以重複使用字典中的單詞。
示例 3:

輸入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
輸出: false

來源:力扣(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,在字符串中增加空格來構建一個句子,使得句子中所有的單詞都在詞典中。返回所有這些可能的句子。

說明:

分隔時可以重複使用字典中的單詞。
你可以假設字典中沒有重複的單詞。
示例 1:

輸入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
輸出:
[
  "cats and dog",
  "cat sand dog"
]
示例 2:

輸入:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
輸出:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
解釋: 注意你可以重複使用字典中的單詞。
示例 3:

輸入:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
輸出:
[]

來源:力扣(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 的最短轉換序列的長度。轉換需遵循如下規則:

每次轉換隻能改變一個字母。
轉換過程中的中間單詞必須是字典中的單詞。
說明:

如果不存在這樣的轉換序列,返回 0。
所有單詞具有相同的長度。
所有單詞只由小寫字母組成。
字典中不存在重複的單詞。
你可以假設 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:

輸入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

輸出: 5

解釋: 一個最短轉換序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的長度 5。
示例 2:

輸入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

輸出: 0

解釋: endWord "cog" 不在字典中,所以無法進行轉換。

來源:力扣(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 的最短轉換序列。轉換需遵循如下規則:

每次轉換隻能改變一個字母。
轉換過程中的中間單詞必須是字典中的單詞。
說明:

如果不存在這樣的轉換序列,返回一個空列表。
所有單詞具有相同的長度。
所有單詞只由小寫字母組成。
字典中不存在重複的單詞。
你可以假設 beginWord 和 endWord 是非空的,且二者不相同。
示例 1:

輸入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

輸出:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]
示例 2:

輸入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

輸出: []

解釋: endWord "cog" 不在字典中,所以不存在符合要求的轉換序列

來源:力扣(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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章