• [leetcode] 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

    For example,

    Given:
    start = "hit"
    end = "cog"
    dict = ["hot","dot","dog","lot","log"]

    Return

      [
        ["hit","hot","dot","dog","cog"],
        ["hit","hot","lot","log","cog"]
      ]
    

    Note:

    • All words have the same length.
    • All words contain only lowercase alphabetic characters.

    https://oj.leetcode.com/problems/word-ladder-ii/

    思路:这道题主要是超时的问题,java的时间卡的比较紧。整体思路还是bfs求最短路径,同时记录下pre节点用于最后从end节点dfs得到所有路径。

      注意因为同一个单词可能在不同的路径中以相同的路径长度出现,所以用完之后不能从dict中删除,对于再次到达已经遍历过的节点,如果距离超过之前的距离则忽略,如果距离相同,也需要添加到pre中(比如例子中的cog对象)。

    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.LinkedList;
    import java.util.Map;
    import java.util.Queue;
    
    public class Solution {
    
        public ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict) {
            dict.add(end);
            ArrayList<ArrayList<String>> res = new ArrayList<ArrayList<String>>();
            HashMap<String, Node> map = new HashMap<String, Node>();
            Queue<String> queue = new LinkedList<String>();
            queue.add(start);
            Node startNode = new Node(1, start);
            startNode.pre.add(null);
            map.put(start, startNode);
    
            while (!queue.isEmpty()) {
                String cur = queue.remove();
                Node curNode = map.get(cur);
                // found
                if (cur.equals(end)) {
                    getPaths(map.get(end), map, new ArrayList<String>(), res);
                    return res;
                }
                for (int i = 0; i < cur.length(); i++) {
                    for (int j = 0; j < 26; j++) {
                        String newStr = makeNewStr(i, j, cur);
                        if (newStr.equals(cur))
                            continue;
    
                        if (dict.contains(newStr)) {
                            if (!map.containsKey(newStr)) {
                                Node newNode = new Node(curNode.dist + 1, newStr);
                                newNode.pre.add(curNode);
                                map.put(newStr, newNode);
                                queue.add(newStr);
                            } else {// different path with the same length
                                Node oldNewNode = map.get(newStr);
                                if (oldNewNode.dist == curNode.dist + 1) {
                                    oldNewNode.pre.add(curNode);
                                }
                            }
    
                        }
    
                    }
                }
    
            }
            return res;
        }
    
        
        private void getPaths(Node end, Map<String, Node> map, ArrayList<String> curPath, ArrayList<ArrayList<String>> paths) {
            if (end == null) {
                paths.add(new ArrayList<String>(curPath));
                return;
            }
    
            for (Node prevNode : end.pre) {
                curPath.add(0, end.str);
                getPaths(prevNode, map, curPath, paths);
                curPath.remove(0);
            }
    
        }
        
        private String makeNewStr(int i, int j, String cur) {
            StringBuilder sb = new StringBuilder(cur);
            sb.setCharAt(i, (char) ('a' + j));
            return sb.toString();
        }
    
        public static void main(String[] args) {
            HashSet<String> set = new HashSet<String>();
            String[] a = { "hot", "dot", "dog", "lot", "log" };
            for (String each : a)
                set.add(each);
            System.out.println(new Solution().findLadders("hit", "cog", set));
        }
    
        private static class Node {
            public int dist;
            public String str;
            public LinkedList<Node> pre = new LinkedList<Node>();;
    
            public Node(int dist, String str) {
                this.dist = dist;
                this.str = str;
            }
    
            public void addPrev(Node pNode) {
                pre.add(pNode);
            }
    
            @Override
            public String toString() {
                return "Node [dist=" + dist + ", str=" + str + ", prev=" + pre + "]";
            }
    
        }
    
    }

    参考:

    http://blog.csdn.net/whuwangyi/article/details/21611433

    http://blog.csdn.net/worldwindjp/article/details/19301355

  • 相关阅读:
    使用Flink实现索引数据到Elasticsearch
    elasticsearch更改mapping(不停服务重建索引)
    elasticsearch篇之mapping
    Elastalert安装及使用
    基于Elastalert的安全告警剖析
    elastalert
    Apache Flink:特性、概念、组件栈、架构及原理分析
    kafka partition(分区)与 group
    用Spring构建企业Java应用程序的方法
    Authentication and Authorization in ASP.NET Web API
  • 原文地址:https://www.cnblogs.com/jdflyfly/p/3825301.html
Copyright © 2020-2023  润新知