题目
Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
Note:
The same word in the dictionary may be reused multiple times in the segmentation.
You may assume the dictionary does not contain duplicate words.
Example 1:
Input: s = “leetcode”, wordDict = [“leet”, “code”]
Output: true
Explanation: Return true because “leetcode” can be segmented as “leet code”.
Example 2:
Input: s = “applepenapple”, wordDict = [“apple”, “pen”]
Output: true
Explanation: Return true because “applepenapple” can be segmented as “apple pen apple”.
Note that you are allowed to reuse a dictionary word.
Example 3:
Input: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
Output: false
思路和代码
就考虑直接从前往后匹配了开始搜子串了,然后全部都是a的test case又没有过,hashset存了结果也没有过。
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
if (s == null || s.length() == 0) {
return false;
}
return helper(s, wordDict, new HashSet<>(), 0);
}
public boolean helper(String s, List<String> wordDict, HashSet<String> set, int index) {
if (index == s.length()) return true;
if (set.contains(s.substring(index, s.length()))) return true;
if (index!= 0) set.add(s.substring(0, index));
for (String temp : new HashSet<>(set)) {
if (s.startsWith(temp, index)) {
if (helper(s, wordDict, set, index + temp.length())) {
return true;
}
}
}
for (String temp : wordDict) {
if (s.startsWith(temp, index)) {
if (helper(s, wordDict, set, index + temp.length())) {
return true;
}
}
}
return false;
}
}
参考了Sample 0s的答案,发现思路基本一样但是这个很快,然后打断点进去看了一下。发现自己存东西的时候思路有误,按照题目要求是有一个成立就直接返回了,所以存这些“正确”值并没有太大的用处,应该是需要做到“不正确”的时候提前返回,不要全部遍历。
下面代码的思路是在第一次进入canReallyBreak函数的时候,就改变memo值,meno[index]=false代表s从index到结尾不能被表示,这样如果中间或结尾有一段不包含在dict内的,那么后面的memo全部是false,每次遍历s到这里就因为不正确而停止了,相当于缩短了s的长度。
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
boolean canBreak = false;
boolean memo[] = new boolean[s.length()];
Arrays.fill(memo, true);
for(String word : wordDict) {
if(s.startsWith(word, 0)) {
// System.out.println("Picking word: "+word);
canBreak = canReallyBreak(s, wordDict, word.length(), memo);
if(canBreak) break;
}
}
return canBreak;
}
public boolean canReallyBreak(String s, List<String> wordDict, int index, boolean[] memo) {
// System.out.println("At index: "+index);
if(index >= s.length()) return true;
if(!memo[index]) return false;
boolean canBreak = false;
for(String word : wordDict) {
if(s.startsWith(word, index)) {
// System.out.println("Picking word: "+word);
canBreak = canReallyBreak(s, wordDict, index + word.length(), memo);
if(canBreak) break;
}
}
memo[index] = canBreak;
return canBreak;
}
}