算法学习day46
算法学习day46
- 1.力扣 139.单词拆分
- 1.1 分析
- 1.2 代码
- 2.参考资料
1.力扣 139.单词拆分
1.1 分析
题目描述:给定一个非空字符串s和一个包含非空单词的列表wordDict,判断s是否可以被空格拆分成为一个 或者多个在字典中出现的单词。
说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
1.确定dp数组以及下标的含义
dp[i]:字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词。
2.确定递推公式
如果确定dp[j]是true,且[j, i]这个区间的的子串出现在字典里,那么dp[i]一定是true。
递推公式: if([j ,i]这个区间的子串出现在字典里 && dp[j]是ture) 那么dp[i] = true。
3.dp数组如何初始化
dp[0]为true.
4.确定遍历顺序
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
本题是先遍历背包,在遍历物品。
5.举例推导dp[i]
1.2 代码
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
// 将字典转换为unordered_set,便于快速查找
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
// dp数组,dp[i]表示s的前i个字符是否能被拆分成字典中的单词
vector<bool> dp(s.size() + 1, false);
// 初始化dp数组,空字符串可以被拆分成一个空单词
dp[0] = true;
// 遍历s的所有子串,寻找子串是否在字典中存在,并且前面的字符串也能被拆分成字典中的单词
for (int i = 1; i <= s.size(); i++) { // 遍历背包
for (int j = 0; j < i; j++) { // 遍历物品
// 截取s的第j个字符到第i个字符组成的子串
string word = s.substr(j, i - j); //substr(起始位置,截取的个数)
// 如果字典中存在该子串,并且前面的字符串也能被拆分成字典中的单词,则dp[i]为true
if (wordSet.find(word) != wordSet.end() && dp[j]) {
dp[i] = true;
}
}
}
// 返回dp[s.size()],表示s的前s.size()个字符能否被拆分成字典中的单词
return dp[s.size()];
}
};
2.参考资料
[代码随想录]