[LeetCode-JAVA] Word Break II
题目:
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog"
,
dict = ["cat", "cats", "and", "sand", "dog"]
.
A solution is ["cats and dog", "cat sand dog"]
.
思路:根据Word Break的思路,需要在每一次设置dp数组为true的时候,同时记录下此时的String,并且继续遍历而不是break
考虑用HashMap来记录,key为对应的dp中的位置i,value为实时可行的List<String>。
首先回顾一下Word Break 每一次位置i之前是否可以被break 遍历substring所有的 (0, j) (j, i) 。
II中需要注意以下两点:
(1) 需要判断dp[j]大小是否为0 当然 只有在第一下切分00的时候需要
(2)对于每一次的(0, j)拼接 都需要循环整个map.get(j)
(3)由于不像I中那样 判断之后直接break 所以在都遍历的时候 需要判断map.get(i)是否为空,为空的话直接添加就好,不为空则取出并且遍历所有的List中的String 进行添加。
代码:
Public Class Solution{ public List<String> wordBreak(String s, Set<String> wordDict) { //好使 但仍然TLE boolean[] isBreak = new boolean[s.length() + 1]; isBreak[0] = true; Map<Integer, List<String>> map = new HashMap<Integer, List<String>>(); for(int i = 0 ; i <= s.length() ; i++) map.put(i, new ArrayList<String>()); for(int i = 1 ; i <= s.length() ; i++){ for(int j = 0 ; j <= i ; j++){ String cur = s.substring(j, i); if(isBreak[j] && wordDict.contains(cur)){ isBreak[i] = true; List<String> temp = new ArrayList<String>(); if(map.get(j).size() == 0){ //注意事项(1) temp.add(cur); } else{// 注意事项(2) for(int k = 0 ; k < map.get(j).size() ; k++){ temp.add(map.get(j).get(k) + " " + cur); } } //注意事项(3) if(map.get(i).size() == 0){ map.put(i, temp); }else{ for(int k = 0 ; k < map.get(j).size() ; k++){ map.get(i).add(temp.get(k)); } } } } } return map.get(s.length()); } }
最后就是在LeetCode中,有一个复杂的用例,直接用上面的也会TLE,需要先进行Word Break中的判断,是否可以Break,如果可以则用上面的获取即可,AC的代码如下:
public class Solution { public List<String> wordBreak(String s, Set<String> wordDict) { boolean[] isBreak = new boolean[s.length() + 1]; isBreak[0] = true; Map<Integer, List<String>> map = new HashMap<Integer, List<String>>(); for(int i = 0 ; i <= s.length() ; i++) map.put(i, new ArrayList<String>()); if(!isBreakHelper(s, wordDict)){ //先进行判断 return new ArrayList<String>(); }else{ for(int i = 1 ; i <= s.length() ; i++){ for(int j = 0 ; j <= i ; j++){ String cur = s.substring(j, i); if(isBreak[j] && wordDict.contains(cur)){ isBreak[i] = true; List<String> temp = new ArrayList<String>(); if(map.get(j).size() == 0){ temp.add(cur); } else{ for(int k = 0 ; k < map.get(j).size() ; k++){ temp.add(map.get(j).get(k) + " " + cur); } } if(map.get(i).size() == 0){ map.put(i, temp); }else{ for(int k = 0 ; k < map.get(j).size() ; k++){ map.get(i).add(temp.get(k)); } } } } } } return map.get(s.length()); } public boolean isBreakHelper(String s, Set<String> wordDict){ if(s == null || s.length() == 0) return true; boolean[] req = new boolean[s.length() + 1]; //到下标为i时 是否可以 req[0] = true; //需要为0 时 判断剩余的全部 for(int i = 1 ; i <= s.length() ; i++){ for(int j = 0 ; j <= i ; j++){ if(req[j] && wordDict.contains(s.substring(j, i))){ req[i] = true; break; } } } return req[s.length()]; } }
改了一上午 竟然败在这个上面了 T.T