判定字符串是否可以进行切分
题目描述:给定一个源字符串,一个字符串字典,判断该字典是否是由源字符串完全分割而来的
如下例子:
Input: s = “leetcode”, wordDict = [“leet”, “code”] Output: true Explanation: Return true because “leetcode” can be segmented as “leet code”. Input: s = “applepenapple”, wordDict = [“apple”, “pen”] Output: true Explanation: Return true because “applepenapple” can be segmented as “apple pen apple”. Note that you are allowed to reuse a dictionary word. Input: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”] Output: false |
题目链接:
https://www.nowcoder.com/questionTerminal/5f3b7bf611764c8ba7868f3ed40d6b2c
(1)描述:
F(i) 表示长度为 i 的字符串可以被切分
(2)递归推演
对以一个长度为 n 的字符串来说,若前 i 个字符组成的字符串可以被切分的话,若第i + 1 到 第n -1 字符也可以在字典中找到,就说明该字符串可以被切分,返回true
这样的话,我们就可以从头开始遍历字符串,将每一个从头到 i 位置组成的字符串是否可以被切分保存下来,直到最终遍历到最后一个字符满足,前面 j 个字符组成的字符串可以被切分,并且 j + 1 到 最后一个字符也可以在字典中找到,就说这个字符串可以被切分。
F(i) = j < i && F(j) && substr(j, i – j)
(3)确定初始值
由上面的分析,我们发现并不能确定第一个字符组成的字符串是否在字典中可以找到
所以我们要自己加上一个空条件,因为空串认为可以在字典中找到,并且由推演功公式发现确定第一个字符组成的字符串能否切分的时候,我们就必须设置 F(0) = true。
(4)返回值
F(s.size())
代码实现:
class Solution {
public:
bool wordBreak(string s, unordered_set<string> &dict)
{
int len_s = s.size();
int len_d = dict.size();
if(s.empty())
return false;
if(dict.empty())
return false;
//因为有一个空条件,所有我们开辟一个len_s + 1 的字符串
vector<bool> ret(len_s + 1, false);
//初始条件
ret[0] = true;
int i = 0, j = 0;
for(i = 1; i <= len_s ;++i)
{
//如果由前i 个字符组成的字符串中可以找到一个由前 j 个字符组成的字符串可以切分并且j~i之间的字符串可以找到
//就认为前 i 个字符组成的字符串可以被切分
for(j = 0;j < i; ++j)
{
if(ret[j] && find(dict.begin(),dict.end(),s.substr(j,i - j)) != dict.end())
{
ret[i] = true;
break;
}
}
}
return ret[len_s];
}
};