[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

你可能感兴趣的:(LeetCode)