代码改变世界

[LeetCode] 139. Word Break_ Medium tag: Dynamic Programming

2019-04-26 11:08  Johnson_强生仔仔  阅读(458)  评论(0编辑  收藏  举报

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
             Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false

这个题目利用dynamic programming,因为是问yes/no,并且跟坐标有关。利用mem, mem[i] means whether the first i characters can be segment,
mem[i] = Or(mem[j] and s[j:i] is in WordDict). 需要注意的是/可以提高效率的是,跟[LeetCode] 132. Palindrome Partitioning II_ Hard tag: Dynamic Programming不同的是第二个
loop不需要每次都从0开始,因为如果我们知道dictionary中最大长度的word,只需要从i - maxlength来判断即可,然后当i 很小的时候有可能小于0, 所以用max(0,i - maxlength)来作为起始点。

T: O(n * maxl * maxl * len(wordDict)) # 前面n * maxl 因为两个loop,maxl * len(wordDict) 是判断一个string是否在wordDict里面的时间。
Code:
class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        # Dynamic programming, T: O(len(s)*l*l*len(wordDict))  S: O(len(s))
        wordDict = set(wordDict)
        n = len(s)
        dp = [False] * (n + 1) # dp[i] means whether the first i characters can be segment
        dp[0] = True
        
        maxLen = max(len(word) for word in wordDict)
        for i in range(1, n + 1):
            for j in range(max(0, i - maxLen), i): #because the word been check should be at most with maxl length
                if s[j: i] in wordDict and dp[j]:
                    dp[i] = True
                    break
        return dp[-1]