Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode"
,
dict = ["leet", "code"]
.
Return true because "leetcode"
can be segmented as "leet code"
.
调用某博客说的很好的一句话:
首先我们要决定要存储什么历史信息以及用什么数据结构来存储信息。
然后是最重要的递推式,就是如从存储的历史信息中得到当前步的结果。
最后我们需要考虑的就是起始条件的值。
一开始所写是一个贪心吧算是,每走一位进行匹配…显然过不了
后来还是得用dp,使dp[i]表示前i位可以被字典里的组成。
用双循环,判断为true有3种情况
true s[0..i] in dictionary
true dp[k] && s[k+1..i] in dictionary
false
即一个字符串自己本身在字典里,或者它的前k位在已经被我们求过为true && 后一部分在字典里
这题其实不难但是不一定立马能想到;
然后有个细节是,找到为true了要立马break,或者 dp[i] = dp[i] | b1 | (b2 & b3) 这样,否则结果会被覆蓋
class Solution {
public:
bool wordBreak(string s, unordered_set<string>& wordDict) {
int n=s.size();
bool dp[n+1];
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++){
for(int k=0;k<i;k++){
bool b1=wordDict.find(s.substr(0,i))!=wordDict.end();
bool b2=dp[k+1];
bool b3=wordDict.find(s.substr(k+1,i-k-1))!=wordDict.end();
//需要及时break啊哥
// if(i==n) printf("val %d %d %d\n",b1,b2,b3);
dp[i]=b1 || (b2 && b3);
if(dp[i]) break;
}
}
return dp[n];
}
};