LeetCode 單詞拆分
給定一個非空字串 s 和一個包含非空單詞列表的字典 wordDict,判定 s 是否可以被空格拆分為一個或多個在字典中出現的單詞。
說明:
拆分時可以重複使用字典中的單詞。
你可以假設字典中沒有重複的單詞。
示例 1:
輸入: s = "leetcode", wordDict = ["leet", "code"]
輸出: true
解釋: 返回 true 因為 "leetcode" 可以被拆分成 "leet code"。
示例 2:
輸入: s = "applepenapple", wordDict = ["apple", "pen"]
輸出: true
解釋: 返回 true 因為 "applepenapple" 可以被拆分成 "apple pen apple"。
注意你可以重複使用字典中的單詞。
示例 3:
輸入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
輸出: false
方法一:回溯法(深度優先搜尋法),即每次從當前剩餘待匹配的串中擷取一段,然後判斷wordDict是否存在,如果存在則繼續下一步的搜尋,否則更改當前的擷取長度,繼續匹配。
但是超時了。。。
class Solution {
public:
set<int> wordLengthSet;//用於儲存wordDict中單詞的長度
map<string, int> wordDictMap;//將string與是否出現關聯
bool wordBreak(string &s, vector<string>& wordDict) {
//首先掃描一遍,獲取wordDict長度的種類
for (auto word : wordDict) {
wordLengthSet.insert(word.size());
wordDictMap[word] += 1;
}
return dfs(s, 0);
}
bool dfs(string &str, int nowIndex) {
int strSize = str.size();
if (nowIndex >= strSize) {
return true;
}
//對長度進行窮舉
for (auto it = wordLengthSet.rbegin(); it != wordLengthSet.rend(); ++it) {
string subS = str.substr(nowIndex, *it);//以nowIndex為起始,獲取*it長的子串
if (wordDictMap[subS] > 0 && dfs(str, nowIndex + *it)) {
return true;
}
}
return false;
}
};
方法二:將回溯法修改為廣度優先搜尋法。但是還是超時了。。。
class Solution {
public:
bool wordBreak(string &s, vector<string>& wordDict) {
if (s == "") {
return true;
}
set<int> wordLengthSet;//用於儲存wordDict中單詞的長度
int strSize = s.size();
//首先掃描一遍,獲取wordDict長度的種類
for (auto word : wordDict) {
wordLengthSet.insert(word.size());
}
queue<int> myQueue;
myQueue.push(0);
int tempQueueSize, tempBegin;
while (!myQueue.empty()) {
tempQueueSize = myQueue.size();
for (int i = 0; i < tempQueueSize; ++i) {
tempBegin = myQueue.front();
myQueue.pop();
for (auto it = wordLengthSet.rbegin(); it != wordLengthSet.rend(); ++it) {
string subS = s.substr(tempBegin, *it);
if (find(wordDict.begin(), wordDict.end(), subS) != wordDict.end()) {
if (tempBegin + *it >= strSize) {
return true;
}
myQueue.push(tempBegin + *it);
}
}
}
}
return false;
}
};
方法三:動態規劃法。
class Solution {
public:
bool wordBreak(string &s, vector<string>& wordDict) {
if (s == "") {
return true;
}
int strSize = s.size();
vector<bool> dp(strSize, false);//dp[i] == true表示[0, i]可以有wordDict拼湊出
for (int i = 0; i < strSize; ++i) {
if (i == 0 || dp[i - 1]) {//只有當i為0(s串起始)或者 [0, i - 1]能拼湊出才有匹配的意義
for (int j = i; j < strSize; ++j) {//對長度進行窮舉
string subS = s.substr(i, j - i + 1);//以i為起始j - i + 1為長度,求子串
if (find(wordDict.begin(), wordDict.end(), subS) != wordDict.end()) {
dp[j] = true;
}
}
}
}
return dp[strSize - 1];
}
};
方法三優化:第二層for迴圈窮舉長度時,比較笨,每一個長度都進行窮舉,但其實wordDict最長的長度都有一個限度,最大值,所以長度窮舉需要控制。
class Solution {
public:
bool wordBreak(string &s, vector<string>& wordDict) {
if (s == "") {
return true;
}
int strSize = s.size();
vector<bool> dp(strSize, false);//dp[i] == true表示[0, i]可以有wordDict拼湊出
//獲取最長字串長度
int maxWordLength = 0;
for (int i = 0; i < wordDict.size(); ++i) {
maxWordLength = max(maxWordLength, (int)wordDict[i].size());
}
for (int i = 0; i < strSize; ++i) {
if (i == 0 || dp[i - 1]) {//只有當i為0(s串起始)或者 [0, i - 1]能拼湊出才有匹配的意義
for (int len = maxWordLength; len > 0; --len) {//對長度進行窮舉
string subS = s.substr(i, len);//以i為起始len為長度,求子串
if (find(wordDict.begin(), wordDict.end(), subS) != wordDict.end()) {
dp[i + len - 1] = true;
}
}
}
}
return dp[strSize - 1];
}
};
相關文章
- LeetCode-139-單詞拆分LeetCode
- 單詞拆分
- LeetCode-單詞規律LeetCode
- LeetCode-079-單詞搜尋LeetCode
- LeetCode-290-單詞規律LeetCode
- 【LeetCode】127. 單詞接龍LeetCode
- 【LeetCode動態規劃#10】完全揹包問題實戰,其三(單詞拆分,涉及集合處理字串)LeetCode動態規劃字串
- LeetCode-434-字串中的單詞數LeetCode字串
- [LeetCode題解]79. 單詞搜尋LeetCode
- leetcode 127. 單詞接龍(C++)LeetCodeC++
- leetcode 整數拆分(c++)LeetCodeC++
- LeetCode-151-翻轉字串裡的單詞LeetCode字串
- LeetCode1160.拼寫單詞(Java+暴力+HashMap)LeetCodeJavaHashMap
- [LeetCode] Short Encoding of Words 單詞集的短編碼LeetCodeEncoding
- leetcode_58_最後一個單詞的長度_簡單LeetCode
- LeetCode題解(0692):前K個高頻單詞(Python)LeetCodePython
- Leetcode 58. 最後一個單詞的長度LeetCode
- 【leetcode 簡單】第十四題 最後一個單詞的長度LeetCode
- LeetCode-343. 整數拆分 - 題解分析LeetCode
- [leetcode 30 串聯所有單詞的子串 10ms]LeetCode
- LeetCode 3014[輸入單詞需要的最少按鍵次數I]LeetCode
- 【LeetCode】290. Word Pattern 單詞規律(Easy)(JAVA)每日一題LeetCodeJava每日一題
- LeetCode每日一題:反轉字串中的單詞 III(No.557)LeetCode每日一題字串
- LeetCode 343. 整數拆分--動態規劃LeetCode動態規劃
- 單詞
- 程式碼隨想錄day 38 || 322 零錢兌換,279 完全平方數,139 單詞拆分
- leetcode刷題之1160拼寫單詞 java題解(超詳細)LeetCodeJava
- LeetCode每日一題: 最後一個單詞的長度(No.58)LeetCode每日一題
- 單一XML文件拆分示例SHXML
- 【Leetcode 346/700】79. 單詞搜尋 【中等】【回溯深度搜尋JavaScript版】LeetCodeJavaScript
- webpack單詞Web
- 【leetcode 49】【字母異位詞分組】LeetCode
- LeetCode題解:127. 單詞接龍,雙向BFS,JavaScript,詳細註釋LeetCodeJavaScript
- 單詞遊戲遊戲
- 0628+單詞
- 0625+單詞
- 單詞搜尋
- 單詞劃分