zoukankan      html  css  js  c++  java
  • [LeetCode#127]Word Ladder

    ---恢复内容开始---

    The problem:

    Given two words (start and end), and a dictionary, find the length of shortest transformation sequence 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"]

    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.

    My analysis:

    This problem's solution is very elegant and tricky! It represents a new kind of problem that could be solved by using abstract graph. 
    The key idea: use the graph to search. But it differs a lot from the previous problem, which has a obvious link or neighbor list of a node. We need to extract this information from a very tricky way. 
    The abstract graph:
    1. represent each String in the dictionary as a node in the graph.
    2. iff two nodes differ in only one character, there is a edge between those two nodes in the graph.
    
    The shortest problem in the grpah:(unweighted graph)
    The breadth first search could layered the nodes in the graph. 
    The path from source node to another node in the breadth first traversal is the shortest path from source node to the node. The distance is the layer the node in. 
    
    It seems that there is no linkage domain, how could we traversal?
    Since we have no link to follow, how about we try all possible pathes according to the requirement!
    The requirement: Only one letter can be changed at a time. It is not hard to simulate. 
    for (int i = 0; i < cur.length(); i++) {
        char[] cur_array = cur.toCharArray();
        for (char c = 'a'; c <= 'z'; c++) {
            cur_array[i] = c;
            String temp = new String(cur_array);
        ...
    }
    However, the while loop could result in all possbile branches(which only differ a character with the current node). We could only search along the edge that existed in the graph, we need to rule out some unreasonable branches.
    if (dict.contains(temp) && !visited.contains(temp)) {
        queue.offer(temp);
        visited.add(temp);
        next_num++;
    }
    
    What a beautful way!!!(fake traversal and rule out!)
    
    Note:
    the above rountine is for continue search, which means we have not reach out the "end(target)" String. However, if we reach the target, we could directly return the distance, cause the target need not to be in the dict. 
    for (int i = 0; i < cur.length(); i++) {
        char[] cur_array = cur.toCharArray();
        for (char c = 'a'; c <= 'z'; c++) {
            cur_array[i] = c;
            String temp = new String(cur_array); 
            if (temp.equals(end))
                return level + 1;
        ...
        }
    }
    
    The time complexity analysis:
    while (!queue.isEmpty()) {
        ...
        for (int i = 0; i < cur.length(); i++) {
        ...
            for (char c = 'a'; c <= 'z'; c++) {
            ...
                if (dict.contains(temp) && !visited.contains(temp)) {
                    queue.offer(temp);
                    visited.add(temp);
                    next_num++;
                }
            }
        }
    }
    The time complexity for the big for loop: Length * 26
    Since we use "dict.contains(temp)" to restrict searching domain. we enter the for loop at most. dict.size() times. 
    thus the total complexity is 
    size(dict) * length * 26
    
    Note:
    Be very careful with the function of "!visited.contains(temp)".
    Unlike Binary, there could be circle in the graph, thus we must use visted set to record all nodes we have visited. Otherwise it would result in infinite loop. Cause we keep on(there might be iterleaves) enqueuing and dequeing it. 

    My solution:

    public class Solution {
        public int ladderLength(String start, String end, Set<String> dict) {
            
            if (start == null || end == null || dict == null || start.length() == 0 || end.length() == 0 || dict.size() == 0)
                return 0;
            
            HashSet<String> visited = new HashSet<String> ();
            Queue<String> queue= new LinkedList<String> ();
            String cur;
            
            queue.offer(start);
            int cur_num = 1;
            int next_num = 0;
            int level = 1;
            
            while (!queue.isEmpty()) {
                cur = queue.poll();
                cur_num-- ; //only intermdiate string need to be in the dict.
                for (int i = 0; i < cur.length(); i++) {
                    char[] cur_array = cur.toCharArray();
                    for (char c = 'a'; c <= 'z'; c++) {
                        cur_array[i] = c;
                        String temp = new String(cur_array); //must do it in this way, only change one char a time. 
                        if (temp.equals(end))
                            return level + 1;
                        if (dict.contains(temp) && !visited.contains(temp)) {//very imprtant checking condition!!!
                            queue.offer(temp);
                            visited.add(temp);
                            next_num++;
                        }
                    }
                }
                
                if (cur_num == 0) {
                    cur_num = next_num;
                    next_num = 0;
                    level++;
                }
            }
            return 0;
        }
    }

    ---恢复内容结束---

  • 相关阅读:
    vue cli3的多环境配置
    【Unity】VSync垂直同步
    css控制中文单词不拐行
    Spring aop 自定义注解 注解声明在类上 aop 前置通知不生效?
    校验日期格式{YYYYMMDD的 java代码
    Spring的@ExceptionHandler注解使用方法
    Pointcut注解表达式@target、@annotation、@within、this、target、within等
    Redisson的简单使用
    JoinPoint和ProceedingJoinPoint区别
    自定义注解详细介绍
  • 原文地址:https://www.cnblogs.com/airwindow/p/4220300.html
Copyright © 2011-2022 走看看