专题:给定words表,找出满足要求的词汇

这一部分针对给定一个词汇表,和目标单词,询问是否能满足相应要求

  1. # 139. Word Break: 通过wordDict中的词能否构成s
  2. # 140, Word Break2, 返回上述路径
  3. # 127. Word Ladder, 从beginWord到endWord,给定wordList
  4. # 126, Word Ladder II, 统计上述最少步数的路径
  5. # 472. Concatenated Words, 找出wordList中由其它单词构成的词
  6. # 1048. Longest String Chain, 列表里可以构成string chain的最长长度
  7. # 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

 

posted @ 2019-11-29 09:41  qldx  阅读(164)  评论(0)    收藏  举报