點擊上方「程式設計師大白」,選擇「星標」公眾號
重磅乾貨,第一時間送達
題目:單詞斷開 給定一個非空的字符串s和一個字典wordDict,字典中包含許多非空的單詞,確定字符串s是否可以分割成通過字典中的一個或多個單詞組成的空格隔開的序列.假定字典中不包含重複的單詞. 舉個例子,給定
s = "leetcode",
dict = ["leet", "code"].上述將返回true,因為"leetcode"可以分割成"leet code". 更新: 參數wordDict已經從原來的字符串的集合更新為字符串的數組,請重新加載代碼的定義以獲取最新改變.
題解算法及複雜度(6 ms) 本問題是確定一個字符串是否能分割成多個單詞,這些單詞都在字典中出現. 由於本題每個組成成分都是單詞,也就是每次在原有字符串的返回true的基礎上增加一個字典中的單詞來組成新的能夠返回true的字符串.發現這是一種全局同一限制性的求解問題,限制條件是每次字符串增加的都是一個存在於字典中的單詞.舉個例子說明一下: 比如字符串是"leetcodeisnice",字典是["leet", "code", "is", "nice"].要想"leetcodeisnice"返回true,需要從後向前尋找一個單詞("nice"),這個單詞在字典中,並且字符串的之前的部分("leetcodeis")本身是返回true的.全局同一限制性的求解問題可以通過動態規划進行求解. 由此,可以得到狀態轉移過程,用dp[i]表示以字符串s中以第i個字符結尾的字符串(0, i - 1)返回true或者false.那麼dp[i]可以通過判斷所有的j截取s得到子串s(j, i - 1)其中0 < j < j - 1存在於字典中,且dp[j - 1]已經求得為true,來確定dp[i]為true,如果不存在滿足上述條件的j,則返回false. 時間複雜度: O(n ^ 2 * len(wordDict)). n表示字符串s的長度,由於需要對每個位置進行求解,並且對於每個位置,需要求解之前的狀態來確定現在的狀態,這樣的複雜度最壞為O(n ^ 2),而每次確定過程中還需要在字典中進行搜索子串是否存在,需要再乘以len(wordDict). 代碼參見本文件夾下solution.cpp
算法正確性舉個例子
// 輸入數據 s = "leetcode", wordDict = ["leet","code"]
// 初始化 dp[0] = true
// i = 1,"l"不存在於字典中
dp[1] = false
// i = 2,"e"不存在於字典中,"le"不存在於字典中
dp[2] = false
// i = 3, "e"不存在於字典中,"ee"不存在於字典中,"lee"不存在於字典中,
dp[3] = false
// i = 4, "t"不存在於字典中,"et"不存在於字典中,"eet"不存在於字典中,"leet"存在於字典中,且dp[i - len("leet")] = true
dp[4] = true
// i = 5,"c"不存在於字典中,"tc"不存在於字典中,"etc"不存在於字典中,"eetc"不存在於字典中,"leetc"不存在於字典中,
dp[5] = false
// i = 6,"o"不存在於字典中,"co"不存在於字典中,"tco"不存在於字典中,"etco"不存在於字典中,"eetco"不存在於字典中,"leetco"不存在於字典中,
dp[6] = false
// i = 7,"d"不存在於字典中, "od"不存在於字典中,"cod"不存在於字典中,"tcod"不存在於字典中,"etcod"不存在於字典中,"eetcod"不存在於字典中,"leetcod"不存在於字典中,
dp[7] = false
// i = 8,"e"不存在於字典中,"de"不存在於字典中, "ode"不存在於字典中,"code"存在於字典中,且dp[i - len("code")] = true
dp[8] = true
// 返回結果
return true注意: 為了減少一下計算量,代碼中把dp[j] == true的判斷放在了查找子串是否屬於字典判斷的前面.
CPP代碼
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
int len = s.length();
vector<bool>dp(len + 1);
dp[0] = true;
for(int i = 1; i <= len; i ++) {
for(int j = i - 1; j >= 0; j --) {
if(dp[j] == true && (find(wordDict.begin(), wordDict.end(), s.substr(j, i-j)) != wordDict.end())) {
dp[i] = true;
break;
}
}
}
return dp[len];
}
};重磅!程式設計師大白交流群-學術微信交流群已成立
額外贈送福利資源!邱錫鵬深度學習與神經網絡,pytorch官方中文教程,利用Python進行數據分析,機器學習學習筆記,pandas官方文檔中文版,effective java(中文版)等20項福利資源
獲取方式:進入群後點開群公告即可領取下載連結
注意:請大家添加時修改備註為 [學校/公司 + 姓名 + 方向]
例如 —— 哈工大+張三+對話系統。
號主,微商請自覺繞道。謝謝!
推薦閱讀
Leetcode題解 SimplifyPath
Leetcode題解 InsertInterval
Leetcode題解 MergeIntervals
Leetcode題解 JumpGame
Leetcode題解 N-Queens
Leetcode題解 Trapping Rain Water
關於程式設計師大白
程式設計師大白是一群哈工大,東北大學,西湖大學和上海交通大學的碩士博士運營維護的號,大家樂於分享高質量文章,喜歡總結知識,歡迎關注[程式設計師大白],大家一起學習進步!