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的第一个字母开始,逐个增加字母去dict里找,如果找到,就继续从下一个位置开始,逐个增加字母去dict里找,如果没找到,就返回false。但是这样算法不争取,比如 s="aaaaaaa",dict=["aaa", "aaaa"],按上面算法返回false,但实际上是可以分割成两个单词的。
错误的原因很简单,有漏掉情况。于是我想到采用暴力的方法, 把所有可能的组合都找出来,只要有组合成功的就返回true。代码如下:
class Solution { boolean ret; public boolean wordBreak(String s, Set<String> dict) { String[] all = dict.toArray(new String[0]); ret = false; nextWord(0, s, all); return ret; } void nextWord(int pos, String s, String[] all) { if (ret) return; if (pos == s.length()) ret = true; for (int i = 0; i < all.length; i++) { if (s.indexOf(all[i], pos) == pos) { nextWord(pos + all[i].length(), s, all); } } } }
但是,这样会超时。LeetCode给出了超时的样例:
s=“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab”
dict=["a", "aa", "aaa", "aaaa", "aaaaa", "aaaaaa", "aaaaaaa"]
我一看,重点是最后哪一个b,于是我想到了,遍历s中的所有字符,看看有没有在dict中没有出现的,如果dict中所有单词都不含这个字符,那么s肯定是不可分解的。
基于此我增加了部分代码:
【Java代码】
class Solution { boolean ret; public boolean wordBreak(String s, Set<String> dict) { String[] all = dict.toArray(new String[0]); ////////////////////////////////////////////////// //如果s中有字母没在dict出现过,那么结果肯定为false for (int i = 0; i < s.length(); i++) { boolean flag = false; for (int j = 0; j < all.length; j++) { if (all[j].indexOf(s.charAt(i)) > -1) { flag = true; break; } } if (!flag) { return false; } } ////////////////////////////////////////////////// ret = false; nextWord(0, s, all); return ret; } void nextWord(int pos, String s, String[] all) { if (ret) return; if (pos == s.length()) ret = true; for (int i = 0; i < all.length; i++) { if (s.indexOf(all[i], pos) == pos) { nextWord(pos + all[i].length(), s, all); } } } }
说这道题是水过的就是因为LeetCode有提示不通过样例,这样我就能根据样例输入输出来修改代码。