leetcode之Word-break

題目

Word-break

Given a string s and a dictionary of wordsdict, determine if s can be segmented into a space-separated sequence of one ormore dictionary words.

For example, given

s ="leetcode",

dict =["leet", "code"].

Return true because"leetcode"canbe segmented as"leet code".

思路:

如果一個單詞存在一種分解方法,分解後每一塊都在字典中,那必定滿足這麼一個條件:對於該單詞的最後一個分割點,這個分割點到單詞末尾所組成的字符串是一個單詞,而這個分割點到單詞開頭所組成的字符串也是可分解的。所以只要驗證滿足這個條件,我們則可以確定這個較長的字符串也是可分解的。

所以我們用外層循環來控制待驗證的字符串的長度,而用內層的循環來尋找這麼一個分割點,可以把字符串分成一個單詞和一個同樣可分解的子字符串。同時,我們用數組記錄下字符串長度遞增時可分解的情況,以供之後使用,避免重複計算。

解法:

動態規劃

首先我們要決定要存儲什麼歷史信息以及用什麼數據結構來存儲信息。然後是最重要的遞推式,就是如從存儲的歷史信息中得到當前步的結果。最後我們需要考慮的就是起始條件的值。

接下來我們套用上面的思路來解這道題。首先我們要存儲的歷史信息res[i]是表示到字符串s的第i個元素爲止能不能用字典中的詞來表示,我們需要一個長度爲n的布爾數組來存儲信息。然後假設我們現在擁有res[0,...,i-1]的結果,我們來獲得res[i]的表達式。思路是對於每個以i爲結尾的子串,看看他是不是在字典裏面以及他之前的元素對應的res[j]是不是true,如果都成立,那麼res[i]true,寫成式子是

時間複雜度:O(n^2)

空間複雜度:O(n)

具體代碼:

public boolean wordBreak(String s,Set<String> dict) {

              if(s == null || s.length() == 0)

                     returntrue;

              boolean[]res = new boolean[s.length() + 1];

              res[0]= true;

              for(int i = 0; i < s.length(); i++) {

                     StringBuilderstr = new StringBuilder(s.substring(0, i + 1));

                     for(int j = 0; j <= i; j++) {

                            if(res[j] && dict.contains(str.toString())) {

                                   res[i+ 1] = true;

                                   break;

                            }

                            str.deleteCharAt(0);

                     }

              }

              returnres[s.length()];

       }


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