package LeetCode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class wordBreak {
/***
* 从问题的要求来看,需要判断是否可以将给定的字符串拆分成若干个子串,使得里面每个子串都可以在给定的字典集中找到。
* 从一种最通用的情况来看,假定一个数组的长度为n。对于里面索引位置为i的点,假设存在有i到n的这一段在集合中可以找到,
* 那么我们这个问题是否有解就取决于前面0到i - 1的这一段的情况了。相当于我们这个问题递归的缩小到更小的串里面了。
而从问题最小的形式来看,对于长度为0的串,我们可以认为它是可以在字典集合中找到的。这样,我们就构成了一个简单的递推关系:
f(n) = for(i = 0; i < n; i++) { if(s.substring(i, n) in set) then f(i) is a possible solution }
既然是这么一个递归的关系,我们如果直接用递归的话,会发现有一些子串的递归情况可能会反复用到。这样可以考虑用动态规划的方法。
在详细的实现里,我们定义一个boolean[n + 1]canBrerak的串。canBreak[0] = true。表示0个字符的情况。
对于后续的元素,我们根据前面的条件来判断设置canBreak[i]的值。只要找到一个满足canBreak[i]为true的值,
我们就可以继续考虑canBreak[i+1]的情况了。
详细的代码实现如下:
* @param s
* @param dict
* @return
*/
public boolean IfwordBreak(String s, List<String> wordDict){
Set<String> dict = new HashSet<String>();
for (int i = 0; i < wordDict.size(); i++) {
dict.add(wordDict.get(i));
}
boolean isTrue[] = new boolean[s.length()+1];
isTrue[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
if(isTrue[j]&&dict.contains(s.substring(j, i))){
//isTrue其实是记录上次在字典种找到对应单词的位置下一个//例如在找到leet的时候,此时i=4,对应的是c这个字符,在下一次
//查找的过程中在j=4之前的位置除去0位置都为false,只有在j=4时才为true,这就表示以后只有在j=4时,才会有可能进入到循环内部,其余的均不可能
isTrue[i] = true;
break;
}
}
}
// System.out.println("count = "+count);
return isTrue[s.length()];
}
public static void main(String[] args) {
/**
String s = "aaaaaaa";
List<String> dict = new ArrayList<String>();
dict.add("aaaa");
dict.add("aaa");
*/
String s = "leetcode";
List<String> dict = new ArrayList<String>();
dict.add("leet");
dict.add("code");
System.out.println(new wordBreak().IfwordBreak(s, dict));
}
}
单词分割(Word Break)
最新推荐文章于 2023-03-14 23:46:40 发布