參考: https://leetcode-cn.com/problems/word-break/solution/dan-ci-chai-fen-by-leetcode/優化
暴力遞歸 超時,時間複雜度:O(N^N), 空間複雜度O(N): 遞歸的深度code
public boolean wordBreak(String s, List<String> wordDict) { return wordBreakSet(s, new HashSet<>(wordDict)); } private boolean wordBreakSet(String s, HashSet<String> wordDict) { if (s.isEmpty()) { return true; } for (int i = 0; i < s.length(); i++) { String before = s.substring(0, i); String after = s.substring(i); if (wordDict.contains(after) && wordBreakSet(before, wordDict)) { return true; } } return false; }
public boolean wordBreak(String s, List<String> wordDict) { return wordBreakSet(s, new HashSet<>(wordDict), new HashSet<>()); } private boolean wordBreakSet(String s, HashSet<String> wordDict, HashSet<String> memory) { if (s.isEmpty()) { return true; } if (memory.contains(s)) return false; //記憶 for (int i = 0; i < s.length(); i++) { String before = s.substring(0, i); String after = s.substring(i); if (wordDict.contains(after) && wordBreakSet(before, wordDict, memory)) { return true; } } memory.add(s); //記憶 return false; }
public boolean wordBreak(String s, List<String> wordDict) { LinkedList<String> queue = new LinkedList<>(); queue.add(s); while (!queue.isEmpty()) { String seg = queue.poll(); for (String word : wordDict) { if (seg.startsWith(word)) { String otherSeg = seg.substring(word.length()); if (otherSeg.isEmpty()) { return true; } queue.add(otherSeg); } } } return false; }
public boolean wordBreak(String s, List<String> wordDict) { LinkedList<String> queue = new LinkedList<>(); queue.add(s); Set<String> memory = new HashSet<>(); //記憶 while (!queue.isEmpty()) { String seg = queue.poll(); if (!memory.contains(seg)) { //記憶 for (String word : wordDict) { if (seg.startsWith(word)) { String otherSeg = seg.substring(word.length()); if (otherSeg.isEmpty()) { return true; } queue.add(otherSeg); } } memory.add(seg); //記憶 } } return false; }
public boolean wordBreak(String s, List<String> wordDict) { boolean[] dp = new boolean[s.length()];//dp[i]表明字符串s截止到下標i時的子字符串是否可拆分,即 s.substring(0,i) 是否可拆分。 dp[0] = true; Set<String> set = new HashSet<>(wordDict); for (int i = 0; i < s.length(); i++) { for (int j = i; j >= 0; j--) { boolean before = dp[j]; String middle = s.substring(j, i); String after = s.substring(i); if (before && (middle.isEmpty() || set.contains(middle)) && set.contains(after)) { return true; } if (before && set.contains(middle)) { dp[i] = true; break; } } } return false; }
public boolean wordBreak(String s, List<String> wordDict) { boolean[] dp = new boolean[s.length() + 1]; dp[0] = true; Set<String> set = new HashSet<>(wordDict); for (int i = 0; i <= s.length(); i++) { //注意邊界條件 for (int j = 0; j < i; j++) { if (dp[j] && set.contains(s.substring(j, i))) { dp[i] = true; break; } } } return dp[s.length()]; }