字符串单词拆分

366 阅读2分钟

1.普通版

题目:

给定一个非空字符串

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

解题思路:

题目的要求就是,一个字符串必须刚好被分为几个单词且这几个单词都在词典里,像实例3那样子交叉着是不行的,要独立分出来(一个单词一个单词的判断,截取需要的单词到最近的字符),其实这样就反而简单了呢。

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n=len(s)
        dp=[False]*(n+1)
        dp[0]=True
        for i in range(n):
            for j in range(i+1,n+1):
                if(dp[i] and (s[i:j]in wordDict)):
                    dp[j]=True
        return dp[-1]

2.升级版

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

说明:

  • 分隔时可以重复使用字典中的单词。
  • 你可以假设字典中没有重复的单词。

示例 1:

输入:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
输出:
[
  "cats and dog",
  "cat sand dog"
]

解题思路:

不能像第一种那样从前往后推, 只能从后往前退,并且运用动态规划+回朔的方法。

from collections import deque
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
        size = len(s)
        assert size > 0
        word_set = {word for word in wordDict}
        dp = [0 for _ in range(size + 1)]#0~size
        dp[0] = 1

        for i in range(1, size + 1):#i: 1~size
            for j in range(i):#j: 0~i-1
                if dp[j] and s[j:i] in word_set:#0~j-1 true; j~i-1 in
                    dp[i] = 1
                    break

        res = []
        queue = deque()
        self.__dfs(s, size, word_set, res, queue, dp)
        return res

    def __dfs(self, s, end, word_set, res, queue, dp):
        if end == 0:
            res.append(' '.join(queue))
            return
        for i in range(end): #0~end-1
            if dp[i]:  #0~i-1 true
                suffix = s[i:end] #i~end-1
                if suffix in word_set:
                    queue.appendleft(suffix)
                    self.__dfs(s, i, word_set, res, queue, dp) #0~i-1
                    queue.popleft()