leetcode140——WordBreakⅡ

題目大意:給出字符串s和字典,用空格拆分字符串s,使得成爲一個或多個在字典中出現的單詞,找出所有可拆分的解。

分析:動態規劃。先用leetcode139判斷是否有解。有解的基礎上:

狀態:二維數組dp[i]——s[0~i-1]的所有可拆分情況(一堆字符串)

初始化:vector<string>均爲空

結果:dp[s.size()]

轉移方程:

如果s[0~i-i]有解——if(!dp[i].empty()) ,就遍歷字典,依次拿出word匹配,如果有匹配當前s[i]的word:

對dp[i]中的每個字符串dp[i][j],dp[i+word.size()].push_back(dp[i][j] + “ ” + word)

代碼:

class Solution {
public:
	vector<string> wordBreak(string s, vector<string>& wordDict) {
		if (!isBreakable(s, wordDict)) return {}; //先判斷是否有解,否則超時
		vector<vector<string>> dp(s.size() + 1, vector<string>());
		for (int i = 0; i < s.size(); i++) { //找從s[i]開始的匹配解
                        //只有當s[0~i-1]有解時才從i開始繼續找解
			if (i == 0 || !dp[i].empty()) { 
                            for (string word : wordDict) {
                                int newEnd = i + word.size();
                                if (newEnd > s.size()) continue;
                                if (s.substr(i, word.size()) != word) continue;
                                if (i == 0) { //注意從0開始的匹配解直接加入答案,不用加" "
                                    dp[newEnd].push_back(word);
                                    continue;
                                }
                                for (string str : dp[i]) {
                                    dp[newEnd].push_back(str + " " + word);
                                }
                            }
                        }	
		}
		return dp[s.size()];
	}

	bool isBreakable(string s, vector<string>& wordDict) {
		unordered_set<string> words(wordDict.begin(),wordDict.end());
                vector<bool> dp(s.size() + 1);
                dp[0] = true;
                for(int i = 1;i <= s.size();i++){
                    for(int j = 0;j < i;j++){
                        if(dp[j] && words.count(s.substr(j,i - j))){
                            dp[i] = true;
                            break;
                        }
                    }
                }
                return dp[s.size()];
	}
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章