Solve Word Break Problem in Java

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given s = “leetcode”, dict = [“leet”, “code”]. Return true because “leetcode” can be segmented as “leet code”.

Solve Word Break Problem in Java

Solution 1:

public class Solution {
public boolean wordBreak(String s, Set<String> dict) {
return wordBreakHelper(s, dict, 0);
}
public boolean wordBreakHelper(String s, Set<String> dict, int start){
if(start == s.length())
return true;
for(String a: dict){
int len = a.length();
int end = start+len;
//end index should be <= string length
if(end > s.length())
continue;
if(s.substring(start, start+len).equals(a))
if(wordBreakHelper(s, dict, start+len))
return true;
}
return false;
}
}

Solution 2:

The key to solve this problem by using dynamic programming approach:
• Define an array t[] such that t[i]==true =>0-(i-1) can be segmented using dictionary
• Initial state t[0] == true

public class Solution {
public boolean wordBreak(String s, Set<String> dict) {
boolean[] t = new boolean[s.length()+1];
t[0] = true; //set first to be true, why?
//Because we need initial state
for(int i=0; i<s.length(); i++){
//should continue from match position
if(!t[i])
continue;
for(String a: dict){
int len = a.length();
int end = i + len;
if(end > s.length())
continue;
if(t[end]) continue;
if(s.substring(i, end).equals(a)){
t[end] = true;
}
}
}
return t[s.length()];
}
}

Time: O(string length * dict size) One tricky part of this solution is the case:

INPUT: “programcreek”, [“programcree”,”program”,”creek”].

We should get all possible matches, not stop at “programcree”.

Solution 3:

Solve Word Break Problem in Java using Regular Expression

The problem is supposed to be equivalent to matching the regexp (leet|code)*, which means that it can be solved by building a DFA in O(2m) and executing it in O(n).

public static void main(String[] args) {
HashSet<String> dict = new HashSet<String>();
dict.add("go");
dict.add("goal");
dict.add("goals");
dict.add("special");
StringBuilder sb = new StringBuilder();
for(String s: dict){
sb.append(s + "|");
}
String pattern = sb.toString().substring(0, sb.length()-1);
pattern = "("+pattern+")*";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher("goalspecial");
if(m.matches()){
System.out.println("match");
}
}

Word Break Problem 2 in Java

Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

For example, given s = “catsanddog”, dict = [“cat”, “cats”, “and”, “sand”, “dog”], the solution is [“cats and dog”, “cat sand dog”].

public static List<String> wordBreak(String s, Set<String> dict) {
//create an array of ArrayList<String>
List<String> dp[] = new ArrayList[s.length()+1];
dp[0] = new ArrayList<String>();
for(int i=0; i<s.length(); i++){
if( dp[i] == null )
continue;
for(String word:dict){
int len = word.length();
int end = i+len;
if(end > s.length())
continue;
if(s.substring(i,end).equals(word)){
if(dp[end] == null){
dp[end] = new ArrayList<String>();
}
dp[end].add(word);
}
}
}
List<String> result = new LinkedList<String>();
if(dp[s.length()] == null)
return result;

ArrayList<String> temp = new ArrayList<String>();
dfs(dp, s.length(), result, temp);
return result;
}
public static void dfs(List<String> dp[],int end,List<String> result,
ArrayList<String> tmp){
if(end <= 0){
String path = tmp.get(tmp.size()-1);
for(int i=tmp.size()-2; i>=0; i--){
path += " " + tmp.get(i) ;
}
result.add(path);
return;
}
for(String str : dp[end]){
tmp.add(str);
dfs(dp, end-str.length(), result, tmp);
tmp.remove(tmp.size()-1);
}
}