• leetcode — word-ladder


    import java.util.*;
    
    /**
     * Source : https://oj.leetcode.com/problems/word-ladder/
     *
     *
     * Given two words (start and end), and a dictionary, find the length of shortest
     * transformation sequence from start to end, such that:
     *
     * Only one letter can be changed at a time
     * Each intermediate word must exist in the dictionary
     *
     * For example,
     *
     * Given:
     * start = "hit"
     * end = "cog"
     * dict = ["hot","dot","dog","lot","log"]
     *
     * As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     * return its length 5.
     *
     * Note:
     *
     * Return 0 if there is no such transformation sequence.
     * All words have the same length.
     * All words contain only lowercase alphabetic characters.
     *
     */
    public class WordLadder {
    
        /**
         *
         * 转化为图的问题
         * start、end、dict中各个单词看做是图中的每个节点
         * 如果有一个单词能变化一个字母到另外一个单词,说明两个节点是连通的
         *
         * 所以就转化为求两个节点之间的最短距离,使用BFS
         *
         * 使用BFS注意:
         * 1. 找到当前需要遍历的节点,这里是当前节点的相邻节点
         * 2. 标记已经遍历过的节点,防止从重复遍历
         *
         * 从start开始使用BFS,遍历当前节点的相邻节点,求出当前节点的相邻节点两种办法:
         * 1. 遍历字典中每个单词,如果和当前单词只差一个字母,说明是相邻的,复杂度为:w*n,w是当前单词的长度,n是字典单词数量
         * 2. 针对当前单词的每个字母,找出可能得变化,每个字母可以变为26个字母中除本身外的其他字母,如果判断变化后的单词在字典中则为相邻的节点,
         *          复杂度为 26*w,w为单词长度
         *
         * 当字典中单词数量较小的时候可以使用第一种方法,如果字典中单词数量较大则使用第二种方法
         *
         * 怎么标记访问过的节点?
         * 已经访问过的节点不需要再次被访问,所以可以从字典中删除
         *
         * 这里使用第二种方法
         *
         * @param start
         * @param end
         * @param dict
         * @return
         */
        public int ladderLength (String start, String end, String[] dict) {
            Set<String> set = new HashSet<String>(Arrays.asList(dict));
            set.add(end);
            Map<String, Integer> map = new HashMap<String, Integer>();
    
            map.put(start, 1);
            while (map.size() > 0) {
                String cur = map.keySet().iterator().next();
                Integer len = map.get(cur);
                if (cur.equals(end)) {
                    System.out.println(len);
    //                return len;
                }
                map.remove(cur);
                Set<String> neighbors = findNeighbors(cur, set);
                for (String str : neighbors) {
                    map.put(str, len+1);
                }
            }
    
            return 0;
    
        }
    
        private Set<String> findNeighbors (String cur, Set<String> dict) {
            Set<String> neighbors = new HashSet<String>();
            for (int i = 0; i < cur.length(); i++) {
                for (int j = 0; j < 26; j++) {
                    char ch = (char) ('a' + j);
                    if (cur.charAt(i) != ch) {
                        String candidate = "";
                        if (i == cur.length()-1) {
                            candidate = cur.substring(0, i) + ch;
                        } else {
                            candidate = cur.substring(0, i) + ch + cur.substring(i+1);
                        }
                        if (dict.contains(candidate)) {
                            neighbors.add(candidate);
                            dict.remove(candidate);
                        }
                    }
                }
            }
            return neighbors;
        }
    
        public static void main(String[] args) {
            WordLadder wordLadder = new WordLadder();
            String start = "hit";
            String end = "cog";
            String[] dict = new String[]{"hot","dot","dog","lot","log"};
            System.out.println(wordLadder.ladderLength(start, end, dict) + "----5");
    
        }
    }
    
  • 相关阅读:
    Effective Java 第三版——26. 不要使用原始类型
    Effective Java 第三版——25. 将源文件限制为单个顶级类
    Effective Java 第三版——24. 优先考虑静态成员类
    Effective Java 第三版——23. 优先使用类层次而不是标签类
    Effective Java 第三版——22. 接口仅用来定义类型
    Effective Java 第三版——21. 为后代设计接口
    Effective Java 第三版——20. 接口优于抽象类
    Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
    Effective Java 第三版——18. 组合优于继承
    Effective Java 第三版——17. 最小化可变性
  • 原文地址:https://www.cnblogs.com/sunshine-2015/p/7864814.html
Copyright © 2020-2023  润新知