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