zoukankan      html  css  js  c++  java
  • Word Ladder II

    Word Ladder II

    问题:

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

    1. Only one letter can be changed at a time
    2. Each intermediate word must exist in the dictionary

    思路:

      bfs dfs结合

    我的代码:

    public class Solution {
        public List<List<String>> findLadders(String start, String end, Set<String> dict) {
            if(isValid(start, end))
            {
                List<String> tmpList = new ArrayList<String>();
                tmpList.add(start);
                tmpList.add(end);
                list.add(tmpList);
                return list;
            }
            Set<String> rst = new HashSet<String>();
            for(String str : dict)
            {
                if(isValid(end,str))
                {
                    rst.add(str);
                }
            }
            List<String> tmpList = new ArrayList<String>();
            dfs(tmpList, rst, dict, start, end);
            List<List<String>> result = new ArrayList<List<String>>();
            for(List<String> partList: list)
            {
                if(partList.size() == shortPath)
                    result.add(partList);
            }
            return result;
        }
        private List<List<String>> list = new ArrayList<List<String>>();
        private int shortPath = Integer.MAX_VALUE;
        public void dfs(List<String> tmpList, Set<String> rst, Set<String> dict, String start, String end)
        {
            tmpList.add(start);
            if(rst.contains(start))  
            {
                tmpList.add(end);
                if(shortPath >= tmpList.size())
                {
                    list.add(new ArrayList(tmpList));
                    shortPath = tmpList.size();
                }
                tmpList.remove(tmpList.size()-1);
                tmpList.remove(tmpList.size()-1);
                return ;
            }
            for(char c = 'a'; c <= 'z'; c++)
            {
                for(int j = 0; j < start.length(); j++)
                {
                    if(start.charAt(j) == c)  continue;
                    String str = replace(start, j, c);
                    if(dict.contains(str))
                    {
                        dict.remove(str);
                        dfs(tmpList, rst, dict, str, end);
                        dict.add(str);
                    }
                }
            }
            tmpList.remove(tmpList.size()-1);
        }
        private String replace(String s, int index, char c)
        {
            char[] chars = s.toCharArray();
            chars[index] = c;
            return new String(chars);
        }
        public boolean isValid(String one, String two)
        {
            int count = 0;
            for(int i = 0; i < one.length(); i++)
            {
                if(one.charAt(i) != two.charAt(i))
                    count++;
            }
            return count == 1 ? true : false;
        }
    }
    View Code

    他人代码:

    public class Solution {
        public List<List<String>> findLadders(String start, String end,
                Set<String> dict) {
            List<List<String>> ladders = new ArrayList<List<String>>();
            Map<String, List<String>> map = new HashMap<String, List<String>>();
            Map<String, Integer> distance = new HashMap<String, Integer>();
    
            dict.add(start);
            dict.add(end);
     
            bfs(map, distance, start, end, dict);
            
            List<String> path = new ArrayList<String>();
            
            dfs(ladders, path, end, start, distance, map);
    
            return ladders;
        }
    
        void dfs(List<List<String>> ladders, List<String> path, String crt,
                String start, Map<String, Integer> distance,
                Map<String, List<String>> map) {
            path.add(crt);
            if (crt.equals(start)) {
                Collections.reverse(path);
                ladders.add(new ArrayList<String>(path));
                Collections.reverse(path);
            } else {
                for (String next : map.get(crt)) {
                    if (distance.containsKey(next) && distance.get(crt) == distance.get(next) + 1) { 
                        dfs(ladders, path, next, start, distance, map);
                    }
                }           
            }
            path.remove(path.size() - 1);
        }
    
        void bfs(Map<String, List<String>> map, Map<String, Integer> distance,
                String start, String end, Set<String> dict) {
            Queue<String> q = new LinkedList<String>();
            q.offer(start);
            distance.put(start, 0);
            for (String s : dict) {
                map.put(s, new ArrayList<String>());
            }
            
            while (!q.isEmpty()) {
                String crt = q.poll();
    
                List<String> nextList = expand(crt, dict);
                for (String next : nextList) {
                    map.get(next).add(crt);
                    if (!distance.containsKey(next)) {
                        distance.put(next, distance.get(crt) + 1);
                        q.offer(next);
                    }
                }
            }
        }
    
        List<String> expand(String crt, Set<String> dict) {
            List<String> expansion = new ArrayList<String>();
    
            for (int i = 0; i < crt.length(); i++) {
                for (char ch = 'a'; ch <= 'z'; ch++) {
                    if (ch != crt.charAt(i)) {
                        String expanded = crt.substring(0, i) + ch
                                + crt.substring(i + 1);
                        if (dict.contains(expanded)) {
                            expansion.add(expanded);
                        }
                    }
                }
            }
    
            return expansion;
        }
    }
    View Code

    学习之处:

    • 我的代码只能过小的数据集,大的数据集就超时了,主要是太多的的重复计算非最短路径中,需要先进行BFS确定哪些是最短的路径
    • 直接复制的别人的代码AC的,有点浮躁啊,看看了,下次再刷leetcode的时候,再自己写一遍,到了hard的难度了,越来越多的题,hold不住了。
    • 改掉自己身上不好的习惯,Day by day, 进步一点点
  • 相关阅读:
    一些点子的梳理
    网络安全解决方案
    流量劫持技术
    运营商DNS系统安全解决方案
    安卓工作室 设置每次启动 选择项目,不直接打开项目
    多臂机测试, AB测试
    vue 入门
    web开发 入门
    C# .NET 使用第三方类库DotNetZip解压/压缩Zip文件
    Linq 101 工具和源码
  • 原文地址:https://www.cnblogs.com/sunshisonghit/p/4515090.html
Copyright © 2011-2022 走看看