单词拆分
给定字符串 s 和单词字典 dict,确定 s 是否可以分成一个或多个以空格分隔的子串,
并且这些子串都在字典中存在.
样例 1:
输入:
"lintcode", ["lint", "code"]
输出:
true
样例 2:
输入:
"a", ["a"]
输出:
true
解答:
定义dp[i][j]为s的前i个字符并且s的第j个字符到第i个字符划分为一个字串时是否可行
则有状态转换方程
dp[i][j] = dp[i][j] || {dp[j-1][j-1] && (if s[j->i] in wordSet)}的或集 {0<= j <=i}
其中当i==j时,dp[i][j]为dp[i][0-j]的或集,即只需要有一个满足,则 dp[i][j]满足
class Solution {
public:
/**
* @param s: A string
* @param wordSet: A dictionary of words dict
* @return: A boolean
*/
bool wordBreak(string &s, unordered_set<string> &wordSet) {
// write your code here
/*
定义dp[i][j]为s的前i个字符并且s的第j个字符到第i个字符划分为一个字串时是否可行
则有状态转换方程
dp[i][j] = dp[i][j] || {dp[j-1][j-1] && (if s[j->i] in wordSet)}的或集 {0<= j <=i}
其中当i==j时,dp[i][j]为dp[i][0-j]的或集,即只需要有一个满足,则 dp[i][j]满足
*/
int m = s.size() + 1;
int n = m;
bool **dp = new bool*[m];
for (int i = 0; i < m; i++) {
dp[i] = new bool[n];
for (int j = 0; j < n; j++) {
dp[i][j] = false;
}
}
dp[0][0] = true;
for (int i = 1; i < m; i++) {
dp[i][0] = wordSet.count(s.substr(0, i)) > 0 ? true : false;
}
// 前i个组成的字符串
for (int i = 1; i < m; i++) {
// 当j位置为最后一个单词划分位置时
for (int j = 1; j <= i; j++) {
dp[i][j] = dp[i][j] || (dp[j-1][j-1] && (wordSet.count(s.substr(j-1, i-j+1)) > 0 ? true : false));
// dp[i][i]为前dp[i][0],dp[i][1],...,dp[i][i-1]的或集
dp[i][i] = dp[i][i] || dp[i][j];
}
}
bool bRet = dp[m-1][m-1];
for (int i = 0; i < m; i++) {
delete[] dp[i];
}
delete[] dp;
return bRet;
}
};