LeetCode: Word Break & Word Break II
Word Break
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"
.
这个可以用递归做,但是会超时。因此可以用DP做。
string中的每一位对应一个boolean,用来标记这位之前的是否可以被分解。
对于string中的第i位,如果存在0<=j<i,table[j] && substring(j, i)是属于dict的,那么table[i]为true;
1 public static boolean wordBreak(String s, Set<String> dict) { 2 boolean[] t = new boolean[s.length()+1]; 3 t[0] = true; 4 for (int i=1; i<=s.length(); i++) { 5 for (int j=0; j<i; j++) { 6 t[i] = t[j] && dict.contains(s.substring(j, i)); 7 if (t[i] == true) break; 8 } 9 } 10 return t[s.length()]; 11 }
Word Break II
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"]
.
A solution is ["cats and dog", "cat sand dog"]
.
网上看了很多方法。。。回溯法(back tracking)与dfs感觉就是一种方法。都是如果当前满足条件,那么继续进行下去,直到最后返回结果或者不满足条件。
思路是这样的:
首先我需要确定第一个空格的位置。所以就是对substring(0, i)判断,直到找到一个属于dict。回溯法就是要找到所有这样满足条件的i,所以i要从0一直循环到s.length - 1.
然后在确定了第一个空格的位置之后,就可以递归判断第二个空格的位置。
递归的终止条件,已经判断到string的末尾了。。。
这个方法可以这么想。我先在String的一个位置插入一个空格,然后在看在哪能插第二个,直到结束。然后遍历可以插第一个空格的位置。
为了避免超时,所以用Word Break的方法判断string是不是可以分解。
1 public static ArrayList<String> wordBreak(String s, Set<String> dict) { 2 ArrayList<String> result = new ArrayList<String>(); 3 if (wordBreak2(s, dict)) { 4 process(s, 0, 0, "", dict, result); 5 } 6 return result; 7 } 8 public static void process(String s, int start, int end, String r, Set<String> dict, ArrayList<String> res) { 9 for (; end <= s.length(); end++) { 10 if (dict.contains(s.substring(start, end))) { 11 String tmp = r + " " + s.substring(start, end); 12 if (end == s.length()) { 13 res.add(tmp.substring(1)); 14 } 15 else { 16 process(s, end, end, tmp, dict, res); 17 } 18 } 19 } 20 return; 21 } 22 23 public static boolean wordBreak2(String s, Set<String> dict) { 24 if (s.equals("") || s == null) return false; 25 boolean[] t = new boolean[s.length()+1]; 26 t[0] = true; 27 for (int i=1; i<=s.length(); i++) { 28 for (int j=0; j<i; j++) { 29 t[i] = t[j] && dict.contains(s.substring(j, i)); 30 if (t[i] == true) break; 31 } 32 } 33 return t[s.length()]; 34 }