• [LeetCode] 140. Word Break II 单词拆分II


    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

    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 = "catsanddog"
    wordDict = ["cat", "cats", "and", "sand", "dog"]
    Output:
    [
      "cats and dog",
      "cat sand dog"
    ]
    

    Example 2:

    Input:
    s = "pineapplepenapple"
    wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
    Output:
    [
      "pine apple pen apple",
      "pineapple pen apple",
      "pine applepen apple"
    ]
    Explanation: Note that you are allowed to reuse a dictionary word.
    

    Example 3:

    Input:
    s = "catsandog"
    wordDict = ["cats", "dog", "sand", "and", "cat"]
    Output:
    []

    139. Word Break 的拓展,那道题只是让判断是否可以拆分,而这道题要求输出所有可能的拆分组合。

    解法:dp + dfs,先用dp计算是否可以拆分,然后用dfs求出具体拆分的组合。

    Java:

    public static List<String> wordBreak(String s, Set<String> dict) {
        //create an array of ArrayList<String>
        List<String> dp[] = new ArrayList[s.length()+1];
        dp[0] = new ArrayList<String>();
     
        for(int i=0; i<s.length(); i++){
            if( dp[i] == null ) 
                continue; 
     
            for(String word:dict){
                int len = word.length();
                int end = i+len;
                if(end > s.length()) 
                    continue;
     
                if(s.substring(i,end).equals(word)){
                    if(dp[end] == null){
                        dp[end] = new ArrayList<String>();
                    }
                    dp[end].add(word);
                }
            }
        }
     
        List<String> result = new LinkedList<String>();
        if(dp[s.length()] == null) 
            return result; 
     
        ArrayList<String> temp = new ArrayList<String>();
        dfs(dp, s.length(), result, temp);
     
        return result;
    }
     
    public static void dfs(List<String> dp[],int end,List<String> result, ArrayList<String> tmp){
        if(end <= 0){
            String path = tmp.get(tmp.size()-1);
            for(int i=tmp.size()-2; i>=0; i--){
                path += " " + tmp.get(i) ;
            }
     
            result.add(path);
            return;
        }
     
        for(String str : dp[end]){
            tmp.add(str);
            dfs(dp, end-str.length(), result, tmp);
            tmp.remove(tmp.size()-1);
        }
    }
    

    Java:

    public List<String> wordBreak(String s, Set<String> wordDict) {
        ArrayList<String> [] pos = new ArrayList[s.length()+1];
        pos[0]=new ArrayList<String>();
     
        for(int i=0; i<s.length(); i++){
            if(pos[i]!=null){
                for(int j=i+1; j<=s.length(); j++){
                    String sub = s.substring(i,j);
                    if(wordDict.contains(sub)){
                        if(pos[j]==null){
                            ArrayList<String> list = new ArrayList<String>();
                            list.add(sub);
                            pos[j]=list;
                        }else{
                            pos[j].add(sub);
                        }
     
                    }
                }
            }
        }
     
        if(pos[s.length()]==null){
            return new ArrayList<String>();
        }else{
            ArrayList<String> result = new ArrayList<String>();
            dfs(pos, result, "", s.length());
            return result;
        }
    }
     
    public void dfs(ArrayList<String> [] pos, ArrayList<String> result, String curr, int i){
        if(i==0){
            result.add(curr.trim());
            return;
        }
     
        for(String s: pos[i]){
            String combined = s + " "+ curr;
            dfs(pos, result, combined, i-s.length());
        }
    } 

    Java:

    public class Solution {
        Map<String, List<String>> done = new HashMap<>();
        Set<String> dict;
    
        public List<String> wordBreak(String s, Set<String> dict) {
            this.dict = dict;
            done.put("", new ArrayList<>());
            done.get("").add("");
    
            return dfs(s);
        }
    
        List<String> dfs(String s) {
            if (done.containsKey(s)) {
                return done.get(s);
            }
            List<String> ans = new ArrayList<>();
    
            for (int len = 1; len <= s.length(); len++) { 
                String s1 = s.substring(0, len);
                String s2 = s.substring(len);
    
                if (dict.contains(s1)) {
                    List<String> s2_res = dfs(s2);
                    for (String item : s2_res) {
                        if (item == "") {
                            ans.add(s1);
                        } else {
                            ans.add(s1 + " " + item);
                        }
                    }
                }
            }
            done.put(s, ans);
            return ans;
        }
    } 

    Python:

    class Solution(object):
        def wordBreak(self, s, wordDict):
            """
            :type s: str
            :type wordDict: Set[str]
            :rtype: List[str]
            """
            n = len(s)
    
            max_len = 0
            for string in wordDict:
                max_len = max(max_len, len(string))
    
            can_break = [False for _ in xrange(n + 1)]
            valid = [[False] * n for _ in xrange(n)]
            can_break[0] = True
            for i in xrange(1, n + 1):
                for l in xrange(1, min(i, max_len) + 1):
                    if can_break[i-l] and s[i-l:i] in wordDict:
                        valid[i-l][i-1] = True
                        can_break[i] = True
    
            result = []
            if can_break[-1]:
                self.wordBreakHelper(s, valid, 0, [], result)
            return result
    
        def wordBreakHelper(self, s, valid, start, path, result):
            if start == len(s):
                result.append(" ".join(path))
                return
            for i in xrange(start, len(s)):
                if valid[start][i]:
                    path += [s[start:i+1]]
                    self.wordBreakHelper(s, valid, i + 1, path, result)
                    path.pop() 

    C++:

    class Solution {
    public:
        vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
            vector<string> res;
            string out;
            vector<bool> possible(s.size() + 1, true);
            wordBreakDFS(s, wordDict, 0, possible, out, res);
            return res;
        }
        void wordBreakDFS(string &s, unordered_set<string> &wordDict, int start, vector<bool> &possible, string &out, vector<string> &res) {
            if (start == s.size()) {
                res.push_back(out.substr(0, out.size() - 1));
                return;
            }
            for (int i = start; i < s.size(); ++i) {
                string word = s.substr(start, i - start + 1);
                if (wordDict.find(word) != wordDict.end() && possible[i + 1]) {
                    out.append(word).append(" ");
                    int oldSize = res.size();
                    wordBreakDFS(s, wordDict, i + 1, possible, out, res);
                    if (res.size() == oldSize) possible[i + 1] = false;
                    out.resize(out.size() - word.size() - 1);
                }
            }
        }
    };
    

      

    类似题目:

    [LeetCode] 139. Word Break 单词拆分

    All LeetCode Questions List 题目汇总

  • 相关阅读:
    在服务器上搭建java环境
    往Android studio中导入类库文件
    Android异步任务AsyncTask
    搭建java环境
    使用安卓实现一个二维码扫描功能(基于Android Studio)
    Android中的runOnUiThread
    网络基础
    Android使用URL访问网络资源
    21天学通VC++
    cometd(转)
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8509044.html
Copyright © 2020-2023  润新知