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"
.
这是个典型的动态规划的问题。boolean数组A[i]表示从0到i是否可以被分词。对于每一个index,找到所有i<index that A[i]=true以及i=0,看s.substring(i,index)是否构成词。如果是,那么A[index]=true.最后返回A[s.length()]。注意这里的右区间是exclusive的。
实际实现没有用boolean数组,而是用了一个ArrayList<Integer>来记录所有的可以被分词的index,这样查找起下标来会稍微快一点。
public class Solution {
public boolean wordBreak(String s, Set<String> dict) {
List<Integer> arr = new ArrayList<Integer>();
//this index is exclusive, so the actual end of the first word should be firstWordIndex-1
int firstWordIndex = 1;
while(firstWordIndex <= s.length()){
String sub = s.substring(0, firstWordIndex);
if(dict.contains(sub)){
arr.add(firstWordIndex);
break;
}
firstWordIndex++;
}
if(arr.isEmpty())
return false;
int index = firstWordIndex + 1;
while(index <= s.length()){
//the substring from the start of s to the current index forms a word
if(dict.contains(s.substring(0, index))){
arr.add(index);
index++;
continue;
}
//check the stored array
for(Integer i : arr){
if(dict.contains(s.substring(i, index))){
arr.add(index);
break;
}
}
index++;
}
if(arr.get(arr.size() - 1) == s.length())
return true;
else
return false;
}
}