Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words.
Note that the same word in the dictionary may be reused multiple times in the segmentation.
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
Constraints:
1 <= s.length <= 300
1 <= wordDict.length <= 1000
1 <= wordDict[i].length <= 20
s and wordDict[i] consist of only lowercase English letters.
classSolution: defwordBreak(self, s: str, wordDict: List[str]) -> bool: min_w = min(len(word) for word in wordDict) max_w = max(len(word) for word in wordDict) words = set(wordDict)
n = len(s) # buffer = [[False] * n for _ in range(n)] buffer = set() for w inrange(min_w, n + 1): for i inrange(n - w + 1): j = i + w - 1 can = w <= max_w and s[i:j+1] in words # can = can or any(buffer[i][p] and buffer[p+1][j] for p in range(i, j)) # buffer[i][j] = can can = can orany((i, p) in buffer and (p + 1, j) in buffer for p inrange(i, j)) if can: buffer.add((i, j))
# return buffer[0][n - 1] return (0, n - 1) in buffer