今天练两个字符串DP ,字符串DP的难点在于 干扰项比较多,到底怎么定义DP方程这个需要想一想。
139. 单词拆分
这个题就必须从原字符串入手,而不能从单词表入手,从0开始扫描到末尾,
dp[i]表示字符串s的前i个字符能否由wordDict中的单词组成。
而这个判定 由 若 i-j 这个字串在列表内且dp[j]=true,那么 dp[i]=true
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
int n = s.size();
vector<int>dp (n+1,false);
set<string>set(wordDict.begin(), wordDict.end());
dp[0]=true;
for (int i =1;i<=n;i++){
for(int j =0;j<i;j++)
if(dp[j] && set.find(s.substr(j,i-j))!=set.end()){
dp[i] = true;
break;
}
}
return dp[n];
}
};
97. 交错字符串
这个题的dp方程可以用 dp[i][j] 来表示由s1的前i个和s2的前j个 可以组成s3的前i+j个
而能否构成就看 dp[i-1][j] 和 dp[i][j-1] 和 s3[i+j] 以及 s1[i],s2[j] 的相等情况
dp(i,j) = [dp(i−1,j) and s1(i−1)=s3 (i+j-1)] or [dp(i,j−1) and s2(j−1) = s3 (i+j-1)]
class Solution {
public:
bool isInterleave(string s1, string s2, string s3) {
if(s3.size()!=s1.size()+s2.size())
return false;
int n= s1.size(),m=s2.size();
vector<vector<int>>dp(n+1,vector<int>(m+1,false));
dp[0][0] =true;
for(int i =0;i<=n;i++)
for(int j =0;j<=m;j++){
if(i<n&&s1[i]==s3[i+j] )dp[i+1][j]|=dp[i][j];
if(j<m&&s2[j]==s3[i+j] )dp[i][j+1]|=dp[i][j];
}
return dp[n][m];
}
};