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 };

 

posted @ 2021-03-31 14:33  habibah_chang  阅读(37)  评论(0编辑  收藏  举报