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

    Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

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

    For example,

    Given:
    beginWord = "hit"
    endWord = "cog"
    wordList = ["hot","dot","dog","lot","log"]

    Return

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

    The solution contains two steps 1 Use BFS to construct a graph. 2. Use DFS to construct the paths from end to start.Both solutions got AC within 1s.

    The first step BFS is quite important. I summarized three tricks

    1) Using a MAP to store the min ladder of each word, or use a SET to store the words visited in current ladder, when the current ladder was completed, delete the visited words from unvisited. That's why I have two similar solutions.

    2) Use Character iteration to find all possible paths. Do not compare one word to all the other words and check if they only differ by one character.

    3) One word is allowed to be inserted into the queue only ONCE. See my comments.

    public class Solution {
        Map<String,List<String>> map;
        List<List<String>> results;
        public List<List<String>> findLadders(String start, String end, Set<String> dict) {     
            results= new ArrayList<List<String>>();
            if (dict.size() == 0)
                return results;
    
            int min=Integer.MAX_VALUE;
    
            Queue<String> queue= new LinkedList<String>();
            queue.add(start);
    
            map = new HashMap<String,List<String>>();
    
            Map<String,Integer> ladder = new HashMap<String,Integer>();
            for (String string:dict)
                ladder.put(string, Integer.MAX_VALUE);
            ladder.put(start, 0);
    
            dict.add(end);
            //BFS: Dijisktra search
            while (!queue.isEmpty()) {
    
                String word = queue.poll();
    
                int step = ladder.get(word)+1;//'step' indicates how many steps are needed to travel to one word. 
    
                if (step>min) break;
    
                for (int i = 0; i < word.length(); i++){
                   StringBuilder builder = new StringBuilder(word); 
                    for (char ch='a';  ch <= 'z'; ch++){
                        builder.setCharAt(i,ch);
                        String new_word=builder.toString();             
                        if (ladder.containsKey(new_word)) {
    
                            if (step>ladder.get(new_word))//Check if it is the shortest path to one word.
                                continue;
                            else if (step<ladder.get(new_word)){
                                queue.add(new_word);
                                ladder.put(new_word, step);
                            }else;// It is a KEY line. If one word already appeared in one ladder,
                                  // Do not insert the same word inside the queue twice. Otherwise it gets TLE.
    
                            if (map.containsKey(new_word)) //Build adjacent Graph
                                map.get(new_word).add(word);
                            else{
                                List<String> list= new LinkedList<String>();
                                list.add(word);
                                map.put(new_word,list);
                                //It is possible to write three lines in one:
                                //map.put(new_word,new LinkedList<String>(Arrays.asList(new String[]{word})));
                                //Which one is better?
                            }
    
                            if (new_word.equals(end))
                                min=step;
    
                        }//End if dict contains new_word
                    }//End:Iteration from 'a' to 'z'
                }//End:Iteration from the first to the last
            }//End While
    
            //BackTracking
            LinkedList<String> result = new LinkedList<String>();
            backTrace(end,start,result);
    
            return results;        
        }
        private void backTrace(String word,String start,List<String> list){
            if (word.equals(start)){
                list.add(0,start);
                results.add(new ArrayList<String>(list));
                list.remove(0);
                return;
            }
            list.add(0,word);
            if (map.get(word)!=null)
                for (String s:map.get(word))
                    backTrace(s,start,list);
            list.remove(0);
        }
    }

    Note:

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

    reference:

    https://leetcode.com/discuss/9523/share-two-similar-java-solution-that-accpted-by-oj

    https://chazyhabit.wordpress.com/2014/07/25/word-ladder-ii-leetcode-18/

  • 相关阅读:
    .NET Core 中依赖注入 AutoMapper 小记
    40款用于简洁网页设计的光滑英文字体【上】
    AOS – 另外一个独特的页面滚动动画库(CSS3)
    分享20个新颖的字体设计草图,带给你灵感
    Cleave.js – 自动格式化表单输入框的文本内容
    CssStats – 分析和优化网站 CSS 代码的利器
    20款 JavaScript 开发框架推荐给前端开发者
    12个用于网站性能优化的最佳的图片压缩工具
    16款最佳的 jQuery Time Picker 时间选择插件
    2016年6月份那些最实用的 jQuery 插件专辑
  • 原文地址:https://www.cnblogs.com/hygeia/p/5136743.html
Copyright © 2011-2022 走看看