139. Word Break 发表于 2022-01-30 DFS(TLE)123456789101112131415161718192021class Solution { public boolean wordBreak(String s, List<String> wordDict) { Set<String> wordSet = new HashSet<>(wordDict); return dfs(s, wordSet, 0); } private boolean dfs(String s, Set<String> wordSet, int startIndex) { if (startIndex == s.length()) { return true; } for (int endIndex = startIndex; endIndex < s.length(); endIndex++) { // word: s[startIndex, endIndex] if (wordSet.contains(s.substring(startIndex, endIndex + 1)) && dfs(s, wordSet, endIndex + 1)) { return true; } } return false; }} DFS + Cache123456789101112131415161718192021222324252627282930class Solution { public boolean wordBreak(String s, List<String> wordDict) { Set<String> wordSet = new HashSet<>(wordDict); Set<Integer> cannotBreakStartIndexSet = new HashSet<>(); return dfs(s, 0, wordSet, cannotBreakStartIndexSet); } private boolean dfs(String s, int startIndex, Set<String> wordSet, Set<Integer> cannotBreakStartIndexSet) { if (cannotBreakStartIndexSet.contains(startIndex)) { return false; } if (startIndex == s.length()) { return true; } // word: s[startIndex, endIndex] for (int endIndex = startIndex; endIndex < s.length(); endIndex++) { String word = s.substring(startIndex, endIndex + 1); if (wordSet.contains(word)) { if (dfs(s, endIndex + 1, wordSet, cannotBreakStartIndexSet)) { return true; } } } cannotBreakStartIndexSet.add(startIndex); return false; }} DP12345678910111213141516171819202122class Solution { public boolean wordBreak(String s, List<String> wordDict) { // 定义 dp[i][j] 为子串 s[i...j] 是否可由字典中的单词拼接出来 // 当不拆分时,判断 wordDict 是否包含 s[i...j] // 当拆分时,遍历分割点 k, dp[i][j] = dp[i][k] && dp[k + 1][j] boolean[][] dp = new boolean[s.length()][s.length()]; Set<String> wordSet = new HashSet<>(wordDict); for (int i = s.length() - 1; i >= 0; i--) { for (int j = i; j < s.length(); j++) { if (wordSet.contains(s.substring(i, j + 1))) { dp[i][j] = true; } for (int k = i; !dp[i][j] && k < j; k++) { dp[i][j] = dp[i][k] && dp[k + 1][j]; } } } return dp[0][s.length() - 1]; }} DP123456789101112131415161718class Solution { public boolean wordBreak(String s, List<String> wordDict) { Set<String> wordSet = new HashSet<>(wordDict); // 定义 dp[i] 为前 i 个字符组成的子串是否可由字典拼接而成 boolean[] dp = new boolean[s.length() + 1]; dp[0] = true; for (int i = 1; i <= s.length(); i++) { // k 为分割点,表示前 k 个字符 for (int k = 0; !dp[i] && k < i; k++) { dp[i] = dp[k] && wordSet.contains(s.substring(k, i)); } } return dp[s.length()]; }} Reference139. Word Break