LeetCode-139 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"
.
题意: 求给定字符串s是否可以由dist中的多个字符串组合而成。
思路:
1. 缩小待求字符创的长度。
wordBreak(str[0,i]) = exists[0] && wordBreak(str[1,i]) || exists[1] && wordBreak(str[2,i]) ... || exists[i] && wordBreak(str[i+1,i]);
其中,exist[i]表示从str.substring(0,i+1)所表示的子串存在dict当中;这种方法在leetcode上运行时超时了,代码如下:
public boolean wordBreak(String s, Set<String> dict) { if(s == null || s.equals("")) return true; else if(dict == null || dict.size() == 0) return false; boolean[] exists = new boolean[s.length()]; for(int i=0; i<s.length(); i++) if(dict.contains(s.substring(0, i+1))) exists[i] = true; for(int i=0; i<s.length(); i++) if(exists[i] && wordBreak(s.substring(i+1), dict)) return true; return false; }
2、使用动态规划
设方法inDict(i, j)可以求从i到j的字符串是否在dict中;
2.1. 对于字符串S="abc",若
inDict(0,0)&&dict(1,2) || dict(0,1)&&dict(2,2) || dict.contains(s) == true; 说明S可以由dict中的字符串构成。
2.2. 对于任意字符串S,同样可以使用1中的方法来求解;
2.3. 为了提供效率,申请一个数组map[n][n]用来存放dict(i,j)的结果,其中n=s.length();
代码如下:
public boolean wordBreak(String s, Set<String> dict) { if("".equals(s)) return true; if(dict.size() == 0) return false; int n = s.length(); boolean[][] map = new boolean[n][n]; for(int length=1; length<=s.length(); length++) { for(int start=0; start<=s.length()-length; start++) { boolean result = false; for(int i=start; i<start+length; i++) { result = map[start][i] && map[i+1][start+length-1]; if(result) break; } if(!result) { result = dict.contains(s.substring(start, start+length)); } map[start][start+length-1] = result; } } return map[0][n-1]; }
3. 动态规划的优化。
第2种方法我们使用一个二维数组来记录str[i,j]表示的子串能否被dict中的元素表示,实际上只要用一个一维数组exists[str.length]就可以完成同样的功能;
exists[i]表示从[0,i+1]的子串可以由dict中的元素表示,那么:
wordBreak(str.substring(0, i))=dict.contains(str) || exist[0] && dict.contains(str.substring(1)) || ... || exist[i-2] && dict.contains(str.substring(i-1))
代码如下:
public boolean wordBreak(String s, Set<String> dict) { if(s == null || s.equals("")) return true; else if(dict == null || dict.size() == 0) return false; boolean[] exists = new boolean[s.length()+1]; exists[0] = true; for(int i=1; i<=s.length(); i++) for(int j=0; j<i; j++) if(exists[j] && dict.contains(s.substring(j,i))) exists[i] = true; return exists[exists.length-1];
}
posted on 2015-03-19 18:17 linxiong1991 阅读(93) 评论(0) 编辑 收藏 举报