专题:给定words表,找出满足要求的词汇
这一部分针对给定一个词汇表,和目标单词,询问是否能满足相应要求
- # 139. Word Break: 通过wordDict中的词能否构成s
- # 140, Word Break2, 返回上述路径
- # 127. Word Ladder, 从beginWord到endWord,给定wordList
- # 126, Word Ladder II, 统计上述最少步数的路径
- # 472. Concatenated Words, 找出wordList中由其它单词构成的词
- # 1048. Longest String Chain, 列表里可以构成string chain的最长长度
- # 79. Word Search,二维字母图搜索单词
# 139. Word Break: 通过wordDict中的词能否构成s,用dfs会超时
def wordBreak(s, wordDict): """ :type s: str :type wordDict: List[str] :rtype: bool """ length = len(s) if not wordDict and s: return False dp = [False for _ in range(length+1)] dp[0] = True minimum = min([len(i) for i in wordDict]) for i in range(minimum,length+1): for j in wordDict: if i>=len(j): dp[i] = dp[i] or (dp[i-len(j)] and s[i-len(j):i]==j) return dp[-1] wordBreak(s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"])
# 140, Word Break2,返回上述路径,但是会遇到无路径的情况下TLE,可以先调取#139题判断其是否可分
# 用dp,dp中的每个元素记住之前的路径 def wordBreak2(s, wordDict): if not wordDict and s: return [] minlength = min(map(len,wordDict)) dp = [[] for _ in range(len(s)+1)] dp[0] = [""] for i in range(minlength,len(s)+1): for word in wordDict: if len(word)<=i: if s[i-len(word):i] == word and dp[i-len(word)]: temp = [ele+" "+word if ele!="" else ele+word for ele in dp[i-len(word)]] dp[i]+=temp return dp[-1]
# 也可以用DFS记住路径的方法 def wordBreak2(s,wordDict): if not canBreak(s, wordDict): return [] length = len(s) ans = [] def dfs(cur,ans,path): if cur == length: ans.append(path[1:]) for word in wordDict: if len(word)<=length-cur and word==s[cur:cur+len(word)]: dfs(cur+len(word),ans,path+' '+word) dfs(0,ans,'') return ans
# 127. Word Ladder, 从beginWord到endWord,给定wordList, 通过wordList最少步数,用bfs记录,可以同时统计步数
import collections def ladderLength(beginWord, endWord, wordList): wordList = set(wordList) queue = collections.deque([[beginWord, 1]]) while queue: word, length = queue.popleft() if word == endWord: return length for i in range(len(word)): for c in 'abcdefghijklmnopqrstuvwxyz': next_word = word[:i] + c + word[i+1:] if next_word in wordList: wordList.remove(next_word) queue.append([next_word, length + 1]) return 0 ladderLength(beginWord = "hit",endWord = "cog",wordList = ["hot","dot","dog","lot","log","cog"])
# 126, Word Ladder II, 统计上述最少步数的路径
def findLadders(beginWord, endWord, wordList): """ :type beginWord: str :type endWord: str :type wordList: List[str] :rtype: List[List[str]] """ if len(beginWord)!=len(endWord): return 0 wordList = set(wordList) visited = set() level = {beginWord:[[beginWord]]} chars = [chr(i) for i in range(ord('a'),ord('z')+1)] while level: if endWord in level: return level[endWord] newlevel = dict() temp = set() for word in level: for i in range(len(word)): for char in chars: newword = word[:i]+char+word[i+1:] if newword in wordList and newword not in visited: if newword not in newlevel: newlevel[newword] = [] newlevel[newword]+=[j+[newword] for j in level[word]] temp.add(newword) visited.update(temp) level = newlevel return [] findLadders(beginWord = "hit",endWord = "cog",wordList = ["hot","dot","dog","lot","log","cog"])
# 472. Concatenated Words, 找出wordList中由其它单词构成的词
# 题目已经说明总共有最多10K左右个单词,总长度不超过600K,说明每个单词长度比较小,在这种情况下,就进行将该单词分割,而不是从已有单词里去找重叠的
# 也可以建立trie,然后dfs查找
def findAllConcatenatedWordsInADict(words): """ :type words: List[str] :rtype: List[str] """ words = set(words) res = [] def dfs(word): for i in range(1,len(word)): prefix = word[:i] suffix = word[i:] if prefix in words and suffix in words: return True if prefix in words and dfs(suffix):#避免重复 return True return False for i in words: if dfs(i): res.append(i) return res
# 1048. Longest String Chain, 列表里可以构成string chain的最长长度
- 每一个元素尝试做减法,如果减后的元素能被找到,则长度+1
- 需要从长度由短到长,做排序
def longestStrChain(words): """ :type words: List[str] :rtype: int """ chains = dict() words = sorted(words,key=len) for word in words: temp = 1 for i in range(len(word)): newword = word[:i]+word[i+1:] if newword in chains: temp = max(temp,chains[newword]+1) chains[word] = temp return max(chains.values()) longestStrChain(["a","b","ba","bca","bda","bdca"])
#79. Word Search,二维字母图搜索单词
def existWord(board, word): if not board: return False directions = [[-1,0],[1,0],[0,-1],[0,1]] m,n = len(board),len(board[0]) def dfs(i,j,k,visited=set()): if k==len(word)-1: return True k=k+1 for direction in directions: x,y = i+direction[0],j+direction[1] if 0<=x<m and 0<=y<n: if (x,y) not in visited and board[x][y]==word[k]: if dfs(x,y,k,visited|{(i,j)}): return True return False for i in range(m): for j in range(n): if board[i][j]==word[0]: if dfs(i,j,k=0,visited=set()): return True return False

浙公网安备 33010602011771号