My First BFS Solution
public boolean wordBreak(String s, List<String> wordDict) { if(wordDict.contains(s)) return true; Queue<String> queue = new LinkedList<>(); for(String word:wordDict){ if(s.startsWith(word)){ queue.add(word); } } while(!queue.isEmpty()){ int size = queue.size(); for(int i=0;i<size;i++){ String tempS = queue.poll(); String subS = s.substring(tempS.length()); if(wordDict.contains(subS)) return true; else { for(String word:wordDict){ if(subS.startsWith(word)){ queue.offer(tempS+word); } } } } } return false; }
My First Backtracking Solution:
public boolean wordBreak(String s, List<String> wordDict) { Set<String> wordSet = new HashSet<>(); for(String word: wordDict){ wordSet.add(word); } return helper(s, wordSet); } private boolean helper(String s, Set<String> set){ if(s.length()==0) return true; for(String word: set){ if(s.startsWith(word)){ if(helper(s.substring(word.length()), set)) return true; } } return false; }
Although the above two solutions are "correct",but they are TLE when running the following test case:
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"
["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]
My Second BFS Solution
In this solution, I added a visited boolean array to record the index that I have dealt with, so the codes will not deal with the the index again and again.
public boolean wordBreak_bfs3(String s, List<String> wordDict) { boolean[] visited = new boolean[s.length()]; if(wordDict.contains(s)) return true; Queue<String> queue = new LinkedList<>(); for(String word:wordDict){ if(s.startsWith(word)){ queue.add(word); visited[0]=true; } } while(!queue.isEmpty()){ int size = queue.size(); for(int i=0;i<size;i++){ String tempS = queue.poll(); if(visited[tempS.length()]) continue; String subS = s.substring(tempS.length()); if(wordDict.contains(subS)) return true; else { for(String word:wordDict){ if(subS.startsWith(word)){ queue.offer(tempS+word); } } } visited[tempS.length()]=true; } } return false; }
My Second Backtrackinng Solution, beat 99%
This solution record the index that has been dealt with too.
boolean[] visited; public boolean wordBreak(String s, List<String> wordDict) { visited = new boolean[s.length()]; Set<String> wordSet = new HashSet<>(); for (String word : wordDict) { wordSet.add(word); } return helper(s, wordSet, 0); } private boolean helper(String s, Set<String> set, int index) { for (String word : set) { if (s.equals(word)) return true; else if (s.startsWith(word)) { int len = word.length(); if (visited[index + len]) continue; if (helper(s.substring(len), set, index + len)) return true; visited[index + len] = true; } } return false; }