Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words.
Note that the same word in the dictionary may be reused multiple times in the segmentation.
Example 1:
**Input:** s = "leetcode", wordDict = ["leet","code"]
**Output:** true
**Explanation:** Return true because "leetcode" can be segmented as "leet code".
Example 2:
**Input:** s = "applepenapple", wordDict = ["apple","pen"]
**Output:** true
**Explanation:** Return true because "applepenapple" can be segmented as "apple pen apple".
Note that you are allowed to reuse a dictionary word.
Example 3:
**Input:** s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
**Output:** false
Constraints:
1 <= s.length <= 300
1 <= wordDict.length <= 1000
1 <= wordDict[i].length <= 20
s and wordDict[i] consist of only lowercase English letters.
All the strings of wordDict are unique.
ac1: DP
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> dict = new HashSet<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] && dict.contains(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[n];
}
}
ac2: DFS + Memorization
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
// edge cases
if (s == null || wordDict == null || s.length() == 0 || wordDict.size() == 0)
return false;
// initialize
Set<String> dict = new HashSet<String>(wordDict);
Boolean[] cache = new Boolean[s.length()];
return dfs(s, 0, dict, cache);
}
private boolean dfs(String s, int start, Set<String> dict, Boolean[] cache) {
// exit
if (start == s.length()) return true;
// check cache, avoid repeat
// careful, must use Boolean, instead of boolean, because need to check if cache[start] has been filled before.
if (cache[start] != null) return cache[start];
// process
for (int e = start + 1; e <= s.length(); e++) {
String w = s.substring(start, e);
if (dict.contains(w) && dfs(s, e, dict, cache)) {
cache[start] = true;
return true;
}
}
// string invalid
cache[start] = false;
return false;
}
}