🍕🎉🥓🎊🚗🐷😱❤😀❣🥙🎇🕵️♀️😎🎑🎁🎉😚🎇
题目:
- 给你一个字符串
s
和一个字符串列表wordDict
作为字典。如果可以利用字典中出现的一个或多个单词拼接出s
则返回true
。注意: 不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例:
- 输入: s = " l e e t c o d e " , w o r d D i c t = [ " l e e t " , " c o d e " ] s = "leetcode", wordDict = ["leet", "code"] s="leetcode",wordDict=["leet","code"]
- 输出: t r u e true true
- 解释: 返回 t r u e true true 因为 " l e e t c o d e " "leetcode" "leetcode" 可以由 " l e e t " "leet" "leet" 和 " c o d e " "code" "code" 拼接成。
解题思路:(动规😋)
- 确定dp数组及下标含义:
dp[i]
:字符串长度为i
的话,dp[i]
为true
,表示可以拆分成一个或多个在字典中出现的单词。 - 确定递推公式:
if([j, i] 这个区间的子串出现在字典里 && dp[j]是true)
那么dp[i] = true
- dp数组初始化:
dp[0] = true
- 确定遍历顺序: 本题是排列问题,先遍历背包(字符串
s
),再遍历物品(字符串列表wordDict
)。
C++版
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
vector<bool> dp(s.size() + 1, false);
dp[0] = true;
for(int i = 1; i <= s.size(); i++) // 遍历背包
for(int j = 0; j < i; j++){ // 遍历物品
string word = s.substr(j, i - j);
if(wordSet.find(word) != wordSet.end() && dp[j]) dp[i] = true;
}
return dp[s.size()];
}
};
时间复杂度:
O
(
n
3
)
O(n^3)
O(n3)
空间复杂度:
O
(
n
)
O(n)
O(n)