每日一題,防止痴呆 = =
思路這道題的思路感覺挺常規的,是遞進式的。
一階段:遞迴
首先容易想到的是遞迴,我們可以直接遞迴來做,思路很清晰。就是首先用unordered_map儲存字典,然後建立遞迴函式can_break(s),其中,每個遞迴函式中,找到第乙個和字典中元素匹配的元素,然後將去掉這個元素後的子串再繼續遞迴,最後就可以遍歷所有的情況,從而求得結果。
當然,這個方法在這裡會超時,畢竟有太多不必要的計算了。
二階段:動態規劃
自然,我們遞迴超時了,就可以考慮用動態規劃來進行求解。我們設 dp[i] 表示字串的前 i 個字元,是否可以拆解。那麼我們進行遞推的時候,如果要求解 dp[i],那麼我們只需要遍歷 dp[0] ~ dp[i - 1],如果其中 dp[j] 為 true,也就是說前 j 個字元已經是可拆的了,那麼我們只要保證 j + 1 ~ i 這個字串在字典中,那麼前 i 個字元就都是可拆的了,這樣就有了遞推關係。時間複雜度是o(n2),相比於前一種已經減少很多了。
三階段:優化的動態規劃
到了上面的方法就是結束了嗎?當然不是,我們還能進行一些常數上的加速。我們上面需要在每次求解 dp[i] 的時候,遍歷所有的 0 ~ i - 1,然而我們可以主動一點,我們在遍歷到 i 的時候,下一步不是去遍歷 0 ~ i - 1,而是去遍歷 wordlist,去求 dp[i + word.size() - 1],這樣就又可以省去一些重複遍歷 dp中元素的時間,比二階段的方法更進一步。
ac**
遞迴解法
class
solution
return
false;}
bool
wordbreak
(string s, vector
& worddict)
return
can_break
(s);}}
;
common 動態規劃解法
class
solution
int s_len = s.
length()
;bool dp[s_len +1]
;for
(int i=
0;i<=s_len;i++
) dp[i]
=false
; dp[0]
=true
;for
(int i=
1;i<=s_len;i++)}
}return dp[s_len];}
};
優化動態規劃解法
class
solution}}
return dp[s_len];}
};
LeetCode每日一題(題139)
題目 題目大意 給出乙個字串s和乙個字串陣列words,判斷s是否能夠拆分成多個words中的字串。分析 這道題比較簡單的方式應該是採用動態規劃來做。對於任意乙個字串中的區間,可以判斷該區間組成的字串是否在字典中,如果是,則這個區間的真假取決於前面那個區間的真假。給出狀態轉移方程dp i dp j ...
Leetcode139題 單詞拆分
給定乙個非空字串 s 和乙個包含非空單詞列表的字典 worddict,判定 s 是否可以被空格拆分為乙個或多個在字典 現的單詞。說明 拆分時可以重複使用字典中的單詞。你可以假設字典中沒有重複的單詞。示例 1 輸入 s leetcode worddict leet code 輸出 true 解釋 返回...
leetcode 139 單詞拆分(好題!)
139.單詞拆分 難度中等340 給定乙個非空字串 s 和乙個包含非空單詞列表的字典 worddict,判定 s 是否可以被空格拆分為乙個或多個在字典 現的單詞。說明 示例 1 輸入 s leetcode worddict leet code 輸出 true解釋 返回 true 因為 leetcod...