139. Word Break
问题:
给定字符串s,和词典wordDict
若s可拆分成多个子串,存在于词典中,则返回true。否则返回false。
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 Constraints: 1 <= s.length <= 300 1 <= wordDict.length <= 1000 1 <= wordDict[i].length <= 20 s and wordDict[i] consist of only lowercase English letters. All the strings of wordDict are unique.
解法:DP
1.状态:
- i: 字符串s[0~i]
2.选择:
- 字符串s[0~i]是否在词典中?
- 字符串s[1~i]是否在词典中 | | s[0]是否在词典中 ?
- 字符串s[2~i]是否在词典中 | | s[0~1]是否在词典中 ?
- ......
- 字符串s[i]是否在词典中 | | s[0~i-1]是否在词典中 ?
以上任意满足,则s[0~i]是符合题意的字符串。
3.状态转移:
- dp[i+1]:字符串s[0~i]是满足题意的字符串,即可拆分为词典单词。
- = OR { j=0~i
- dp[j] && s[j~i] in wordDict
- }
4.base:
dp[0]=true
代码参考:
1 class Solution { 2 public: 3 //dp[i+1]:s[0~i]: can be matched ? 4 //opt: OR : 5 //case_1: dp[0] && s[0~i] in wordDict 6 //case_2: dp[1] && s[1~i] in wordDict 7 //... 8 //case_n: dp[i] && s[i] in wordDict 9 //base: dp[0]=true 10 bool wordBreak(string s, vector<string>& wordDict) { 11 int n = s.length(); 12 unordered_set<string> wD(wordDict.begin(), wordDict.end()); 13 vector<bool> dp(n+1, false); 14 dp[0]=true; 15 for(int i=1; i<=n; i++) { 16 for(int j=0; j<=i; j++) { 17 if(dp[j]) { 18 string sub = s.substr(j, i-j); 19 dp[i] = (wD.count(sub)>0); 20 if(dp[i]) break; 21 } 22 } 23 } 24 return dp[n]; 25 } 26 };