zoukankan      html  css  js  c++  java
  • 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);
            }
        }
  • 相关阅读:
    python基础008----Python中类/函数/模块的简单介绍
    linux基础004---用户管理、用户登录注销、系统关机重启
    python基础006----流程控制&推导式&深浅拷贝
    python基础005----字典&集合
    python基础004----列表&元组
    难缠的布隆过滤器,这次终于通透了
    C# 位图BitArray 小试牛刀
    以步步为营的风格解读 Redis分布式锁
    你是不是对MD5算法有误解?
    最适合新手的Redis Cluster搭建过程
  • 原文地址:https://www.cnblogs.com/skillking/p/9776632.html
Copyright © 2011-2022 走看看