祥和是一个动态规划问题,原因在于每个地方都有可能作为分割点,在“可以”作为分割点的情况下,不一定就要在这里分割,例如:
一直s="aaaaaaa"共7个'a',字典{“aaa", "aaaa"}。如果把前6个a分成了2组”aaa",那么剩下的一个就分割不了,所以说这里要讨论的是到index处可不可以分割成完整的,再例如
index1, index2, index3代表3个位置的索引,如果想要知道1~index3可不可以分解,我们已知0~index2可不可以分解,剩下的就是判断index2+1~index3是不是word,如果不可以,也不能说明什么,说明如果真的在这里分割了,那么后面就不成立了,所以虽然0~index2可以完整分割,我们 不一定接受这个建议。继续往前,0~index1之间也是可以完整分割的,那么就来分析index1~index3是不是word。。。注意,这里说的是indexx~index3之间是否存在word而不是可不可以分割
动态规划特点是反向推,根据子问题求解现在的问题。
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
std::vector<bool> flag(s.length()+1, false);
flag[0] = true;
for(int i = 0; i < s.length(); ++i){//包括i可分,保存在i+1位置,例如0位置可分的flag在1
for(int j = i-1; j >= -1; --j){
if(flag[j+1] && wordSet.count(s.substr(j+1, i-j))){
flag[i+1] = true;
break;
}
}
}
return flag.back();
}
};
c++代码上的注意;
1、这里用了unorderd_set,好处unordered哈希表,查找速度快,set与map相比只需要保存一种数据类型;
2、我也没想到vector竟然真的可以初始化unordered_set,那set肯定也可以了;
3、flag的设置,用于标志截止到某个位置,是否可分,这里flag[i]实际上保存的是截止且包含s[i-1]是否可分,flag[0]保存的是s[-1],这个位置的意义在于,虚拟出来一个initial,也就是是s[-1]这么个肯本不存在的东西,因为需要使用它去初始化s[0]对应的bool标志位