140. Word Break II

一、题目

  1、审题

  2、分析

    给出一个字符串,求其可以切割成字典List 中的元素的所有切法。

二、解答

  1、思路:

    方法一、

      采用 DFS 方式。

      从字典表中开始拿字符串与 S 的头部进行匹配,若匹配成功,则继续拿字典表在 S 的剩下的字符串进行匹配。直至 S 剩下的字符串为空,此时就找到一种切法。

      最终返回所有切法的 List。

    public List<String> wordBreak23(String s, List<String> wordDict) {
        return DFS(s, wordDict, new HashMap<String, ArrayList<String>>());
    }
    
    private List<String> DFS(String s, List<String> wordDict,
            HashMap<String, ArrayList<String>> map) {

        if(map.containsKey(s))
            return map.get(s);
        
        ArrayList<String> res = new ArrayList<>();
        
        for(String word: wordDict) {    
            if(s.startsWith(word)) {    // 暴力尝试法
                String next = s.substring(word.length());
                if(next.length() == 0)
                    res.add(word);
                else { 
                    List<String> subList = DFS(next, wordDict, map);
                    for(String sub : subList)
                        res.add(word + " " + sub);
                }
            }
        }
        map.put(s, res);
        return res;
    }

  

  方法二、

    采用 DP + DFS方式。

    ①、首先采用 DP 构造 S 的切割子串的图结构;

    ②、采用 DFS 根据图结构生成所需的 List;

public List<String> wordBreak(String s, List<String> wordDict) {
        List<String> list = new ArrayList<>();
        
        int len = s.length();
        boolean dp[] = new boolean[len + 1];
        Set<String> dict = new HashSet<>(wordDict);
        HashMap<Integer, List<Integer>> prev = new HashMap<>();
        
         //init
        dp[0] = true;
        for (int i = 1; i <= len; i++) 
            prev.put(i, new ArrayList<Integer>());
        
        //step1:construct graph
        for (int i = 1; i <= len; i++) {
            for (int j = 0; j < i; j++) {
                if(dp[j] && dict.contains(s.substring(j, i))) {
                    dp[i] = true;
                    prev.get(i).add(j);
                }
            }
        }
        
        if(!dp[len])
            return list;
        
        //step2: generate the list
        StringBuilder sb = new StringBuilder();
        dfsHelper(len, sb, prev, s, list);
        
        return list;
    }
    
    private void dfsHelper(int len, StringBuilder sb, HashMap<Integer, List<Integer>> prev, String s, List<String> list) {
        
        //base
        if(len == 0) {
            StringBuilder res = new StringBuilder(sb);
            res.deleteCharAt(0);
            list.add(String.valueOf(res));
            return;
        }
        
        List<Integer> prevIndex = prev.get(len);
        for(int i : prevIndex) {
            sb.insert(0, s.substring(i, len)).insert(0, " ");
            dfsHelper(i, sb, prev, s, list);
            sb.delete(0, (len - i) + 1);
        }
    }
原文地址:https://www.cnblogs.com/skillking/p/9776632.html