(Leetcode 127) Word Ladder (medium)

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
Notice
  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
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.

思路

找最短路径,可以将已知的word看成一个graph,找这个graph的最短路径。但问题是这个graph并未告知,需要自己找

关键点有3

  1. 如何找当前word的邻居:26个字母依次替换
    由于题目说2个相关单词只能是差别一个字母,那么我们可以遍历当前单词的每一个字母,将该字母逐一替换成a – z,然后看这替换过的26个单词是否在已知的dict中,如果是,则这些单词就是当前单词的邻居。
    • 单独写一个函数来返回当前word的neighbors:List
    • 把这些neighbor单词加到queue中,作为当前层来判断,该层中是否有target。
  2. 如何标记已经遍历过的单词: hashset去重
    比如我们已经找到hit的邻居是hot,当我们在找hot的邻居的时候,因为hit已经被遍历过了,就不能再遍历了,不能被返回为neighbors。
    • 可以用set来标记已经找到过的单词。 认为,加入queue的,就是已经找到过的了。
    • 在找neighbors的时候,判断当前词是否在set中已经存在,如果存在,则跳过它。
  3. 不要忘记求shortest path其实是求一共多少层,需要加一层 loop循环 queue.size()
public class Solution {
    /**
      * @param start, a string
      * @param end, a string
      * @param dict, a set of string
      * @return an integer
      */
    public int ladderLength(String start, String end, Set dict) {
        
        if (dict == null) {
            return 0;
        }
        
        if (start.equals(end)) {
            return 1;
        }
        
        // 需要把已知的start和end都加入到dict中,这样才能在后续的找当前单词的邻居时,找到end。
        dict.add(end);
        
        Queue queue = new LinkedList();
        Set set = new HashSet();
        queue.add(start);
        set.add(start);
        
        List neighbors = new ArrayList();
        int size = 0;
        int len = 1;
        
        while (!queue.isEmpty()) {
            size = queue.size();
            len++;
            
            for (int i = 0; i < size; i++) {
                String curStr = queue.poll();
                neighbors = this.getNeighbors(curStr, dict, set);
                
                for (String neighbor : neighbors) {
                    if (neighbor.equals(end)) {
                        return len;
                    }
                    
                    queue.add(neighbor);
                    set.add(neighbor);
                 }
            }
        }
        return -1;
        
    }
    
    private List getNeighbors(String curStr, Set dict, Set set) {
        List neighbors = new ArrayList();
        
        for (int i = 0; i < curStr.length(); i++) {
            for (char c = 'a'; c <= 'z'; c++) {
                //是它自己就跳过,因为不是他自己的变形
                if (curStr.charAt(i) == c) {
                    continue;
                }
                
                //单词逐个字母替换, temp必须是每次重新从curStr中获取,否则会被上一次结果污染
                char[] temp = curStr.toCharArray();
                temp[i] = c;
                String curStrTemp = String.valueOf(temp);
                
                if (dict.contains(curStrTemp) && set.contains(curStrTemp) != true)  {
                    neighbors.add(curStrTemp);
                }
            }
        }
        return neighbors;
    }  
}

你可能感兴趣的:((Leetcode 127) Word Ladder (medium))