This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Approach #1 DFS + MEMO O(n * 3) T O(n * n) S | |
// Approach #2 DP O(n * 3) T O(n * n) S | |
// With maxLength optimization it can be O(n * maxLength * maxLength). | |
// Approach #1 DFS + MEMO O(n * 3) T O(n * n) S | |
public class Solution { | |
/** | |
* @param s: A string | |
* @param dict: A set of word | |
* @return: the number of possible sentences. | |
*/ | |
public int wordBreak3(String s, Set<String> dict) { | |
// handle corner cases | |
if (dict == null || dict.size() == 0 || s == null || s.length() == 0) { | |
return 0; | |
} | |
// make it case insensitive | |
Set<String> words = new HashSet<>(); | |
for (String word : dict) { | |
words.add(word.toLowerCase()); | |
maxLength = Math.max(maxLength, word.length()); | |
} | |
// prep for MEMO | |
dp = new int[s.length()][s.length()]; | |
for (int[] row : dp) { | |
Arrays.fill(row, -1); | |
} | |
// perform the MEMO search | |
return dfs(words, s.toLowerCase(), 0, s.length() - 1); | |
} | |
private int maxLength; | |
private int[][] dp; | |
private int dfs(final Set<String> words, final String originalString, final int left, final int right) { | |
if (left > right) { | |
return 1; | |
} | |
if (dp[left][right] != -1) { | |
return dp[left][right]; | |
} | |
int counter = 0; | |
for (int i = left; i <= right && (i - left < maxLength); i++) { | |
String word = originalString.substring(left, i + 1); | |
if (!words.contains(word)) { | |
continue; | |
} | |
counter += dfs(words, originalString, i + 1, right); | |
} | |
dp[left][right] = counter; | |
return dp[left][right]; | |
} | |
} | |
// Approach #2 DP O(n * 3) T O(n * n) S | |
public class Solution { | |
/** | |
* @param s: A string | |
* @param dict: A set of word | |
* @return: the number of possible sentences. | |
*/ | |
public int wordBreak3(String s, Set<String> dict) { | |
// handle corner cases | |
if (dict == null || dict.size() == 0 || s == null || s.length() == 0) { | |
return 0; | |
} | |
// make words case insensitive | |
Set<String> words = new HashSet<>(); | |
int maxLength = 0; | |
for (String word : dict) { | |
words.add(word.toLowerCase()); | |
maxLength = Math.max(maxLength, word.length()); | |
} | |
// dp initialize | |
String string2Break = s.toLowerCase(); | |
int stringLength = string2Break.length(); | |
int[][] dp = new int[stringLength][stringLength]; | |
for (int i = 0; i < stringLength; i++) { | |
for (int j = i; j < stringLength && (j - i < maxLength); j++) { | |
String sub = string2Break.substring(i, j + 1); | |
if (words.contains(sub)) { | |
dp[i][j] = 1; | |
} | |
} | |
} | |
// dp fill the rest with dual-for loop | |
for (int i = 0; i < stringLength; i++) { | |
for (int j = i; j < stringLength; j++) { | |
for (int k = i; k < j; k++) { | |
dp[i][j] += dp[i][k] * dp[k + 1][j]; | |
} | |
} | |
} | |
return dp[0][stringLength - 1]; | |
} | |
} |
No comments:
Post a Comment