leetcode 139 單詞拆分
阿新 • • 發佈:2018-12-03
給定一個非空字串 s 和一個包含非空單詞列表的字典 wordDict,判定 s 是否可以被空格拆分為一個或多個在字典中出現的單詞。
說明:
- 拆分時可以重複使用字典中的單詞。
- 你可以假設字典中沒有重複的單詞。
示例 1:
輸入: s = "leetcode", wordDict = ["leet", "code"] 輸出: true 解釋: 返回 true 因為 "leetcode" 可以被拆分成 "leet code"。
動態規劃
用一個一維的dp陣列,其中dp[i]表示範圍[0, i)內的子串是否可以拆分,注意這裡dp陣列的長度比s串的長度大1,是因為我們要handle空串的情況,我們初始化dp[0]為true,然後開始遍歷。注意這裡我們需要兩個for迴圈來遍歷,因為此時已經沒有遞迴函數了,所以我們必須要遍歷所有的子串,我們用j把[0, i)範圍內的子串分為了兩部分,[0, j) 和 [j, i),其中範圍 [0, j) 就是dp[j],範圍 [j, i) 就是s.substring(j, i),其中dp[j]是之前的狀態,我們已經算出來了,可以直接取,只需要在字典中查詢s.substring(j, i)是否存在了,如果二者均為true,將dp[i]賦為true,並且break掉,此時就不需要再用j去分[0, i)範圍了,因為[0, i)範圍已經可以拆分了。最終我們返回dp陣列的最後一個值,就是整個陣列是否可以拆分的布林值了。
public boolean wordBreak(String s, List<String> wordDict) { int n = s.length(); boolean[] dp = new boolean[n + 1]; dp[0] = true; for(int i = 1; i <= n; i++){ for(int j = 0; j < i; j++){ if(dp[j] && wordDict.contains(s.substring(j, i))){ dp[i] = true; break; } } } return dp[n]; }