题目 leetcode 139.单词拆分
Question: 是否可以将s用空格拆成wordDict中的单词?
思路
将s用substr函数拆开,再与wordDict中每个单词匹配。
(s长度为n)在s[0…I]匹配的情况下,s[i+1…n-1]也匹配,则s可被wordDict中的单词拆分。
(这里被拆分两次,也可以拆分更多次)
采用动态规划实现,具体思路如下:
step1: 初始化dp[n+1]=[false,false,…,false]。dp[I]:s前I位可以被wordDict中的单词表示。
step2: 遍历i,遍历区间[0,n-1]。在前i位可以被拆分为wordDict中单词的情况下:遍历wordDict中的单词word,将与[i,i+word.size()]子串与word进行匹配,匹配成功则s中前I+word.size()位可被拆分wordDict中的单词,并令dp[I+word.size()] = true。
//代码后有注意点
以下是AC代码
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
int n = s.size();
vector<bool> dp(n+1,false);
dp[0] = true;
for(int i = 0; i < n; i++) {
if(!dp[i])
continue;
for(auto& word : wordDict) {
if((i + word.size()) <= n && s.substr(i,word.size()) == word)
dp[i+word.size()] = true;
}
}
return dp[n];
}
};
注意:
1: dp[0] = true,是为了作为匹配的开始。作为状态转移做的一个初始化。
2:只有dp[i] = true时,才能去匹配,是因为需要先保证dp[i] = true,即i之前的内容是可以匹配的,才能在匹配成功后保证s中前i+word.size()位都可以匹配。
3:在匹配wordDict中的单词时,不加&的话每次都要把wordDict里的元素拷贝给word,加了就直接引用,不用拷贝,可以提高运行效率
4:关于substr的用法:(详细参考c++中substr的用法)
形式 : s.substr(position, length)
返回值: string,包含s中从position开始的length个字符的拷贝