Leetcode word break I & II 词句拆分I和II的java实现及解析

word break i是leetcode 里面中等难度的题目而word break II 更是hard题目,两种实现也有所区别,题目也比较迷惑,让我们先看看第一题吧

java DBF文件拆分 java拆分word_字符串


java DBF文件拆分 java拆分word_字符串_02

这一题其实看到也是觉得非常懵,好像除了暴力解法没有什么更好的方法,但是暴力解肯定会TLE的,后来看到了大神的解法之后才想到用DP去解决,不过DP也确实是博主最不擅长的算法了。让我们看看怎么用DP来做,首先我们有一个长度比字符串大1的布尔值的数组来表示到当前位置是否可以被词典中的词构成。利用i来遍历字符串中的每一个字符,再利用迭代器去遍历词典,如果当前词典数字下标加词的长度得到的字符字串等于当前遍历到的字符串的话,那我们就把数组里面的i+ word.length为true,然后我们跳过中间的false,这样就可以获得比较高的效率, 最后我们得到的时间复杂度应该是O(mn),文字的分析可能会有一些难理解,让我们看看代码吧。

class WordBreak{
	public boolean wordBreak(String s, List<String> wordDict){
		boolean[] dp = new boolean[s.length()+1];
		dp[0] = true;
		for(int i = 0; i <= s.length();i++){
			if(dp[i] == false) continue;
			for(String word: wordDict){
				if(i + word.length() > s.length()) continue;
				if(s.substring(i,i+word.length()).equals(word)){
					dp[i+word.length()] = true;
				}
			}
		}
		return dp[s.length()];
	}
}

配合代码加上我们的文字分析应该就是比较好理解的了。再让我们看看第二题吧

java DBF文件拆分 java拆分word_算法_03


java DBF文件拆分 java拆分word_java_04

这一题的要求就比较不一样了,要求返回一个数组,里面每一个元素都是一个字符串,这个字符串就是用字典里面的词来分割的当前的字符串,这个数组里面的字符串就包含了所有的分割方式。这里我们使用的应该是类似DFS+记忆的方式来解决这个问题,我们建立一个哈希表用于记录当前的字符串和当前字符串的分割方法的数组。然后我们不断的将数组分为两个部分,subString(0,i) 和substring(i,end) 这两个部分,我们自后向前的处理这个问题,当subString(i,end)出现在词典里的时候,我们就进行一次分割,将substring(0,i)进行递归处理,然后将递归处理得到的字符串的尾部都加上subString(i, end),最后存入哈希表中,如果在哈希表中发现了一样的key则之间返回该key的value组合。
让我们看看代码吧,同样也是结合代码会比较好理解一点。

class WordBreak{
	private Map<String,List<String>> map = new HashMap<>();
	public List<String> wordBreak(String s, List<String> wordDict){
		List<String> res = new ArrayList<>();
		// 已经遇到过一次了
		if(map.containsKey(s))return map.get(s);
		// 当前字符串自己就是一个组合了
		if(wordDict.contains(s)) res.add(s);
		
		for(int i = 1; i < s.length();i++){
			//分成两个部分
			String suffix = s.substring(i);
			if(wordDict.contains(suffix)){
				List<String> tmp = wordBreak(s.substring(0,i),wordDict);
				for(String str:tmp){
					res.add(str +  " " + suffix);
				}
			}
		}
		map.put(s,res);
		return res;
	}
}

结合代码来看分析应该就能很好的解决这个问题了!