lintcode121- Word Ladder II- hard

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
 Notice
  • 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"]

Return

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

算法:BFS+DFS。

先BFS一次,从终点往回层级遍历,记录dict一部分单词到终点的距离Map<String, Integer> map。

再DFS一次,每次尝试加新节点,要求 1.新节点在map里,说明节点是dict里可能出现在最短路径上的那一部分单词。2.map.get(新节点) < map.get(上一节点)说明你这一步能让你离终点更近,不是鸡肋步。一直加到加入了end点那就结束了。

public class Solution {
    /*
     * @param start: a string
     * @param end: a string
     * @param dict: a set of string
     * @return: a list of lists of string
     */
    public List<List<String>> findLadders(String start, String end, Set<String> dict) {
        // write your code here
        List<List<String>> result = new ArrayList<>();
        List<String> list = new ArrayList<String>();
        list.add(start);
        if (start.equals(end)) {
            // 切记arraylist的构造器deepcopy方法不是把元素传进去,是把同等级的含有元素的collection传进去
            //result.add(new ArrayList<String>(start));
            result.add(list);
            return result;
        }
        if (dict == null) {
            return result;
        }
        
        Map<String, Integer> remDist = bfs(start, end, dict);
        dfs(start, end, remDist, list, result);
        return result;
        
    }
    
    private void dfs(String start, String end, Map<String, Integer> remDist, List<String> crt, List<List<String>> result) {
        // 应该可以去掉一个记录crt里面有什么字符串的set参数吧?因为remDist默默起了相似的帮助去重的作用
        
        if (start.equals(end)) {
            result.add(new ArrayList<String>(crt));
        }
        
        for (int idx = 0; idx < start.length(); idx++) {
            for (char c = 'a'; c <= 'z'; c++) {
                String newStr = changeChar(start, idx, c);
                if (!remDist.containsKey(newStr) || remDist.get(newStr) >= remDist.get(start)) {
                    continue;
                }
                crt.add(newStr);
                dfs(newStr, end, remDist, crt, result);
                crt.remove(crt.size() - 1);
            }
        }
    }
    
    private Map<String, Integer> bfs(String start, String end, Set<String> dict) {
        
        Map<String, Integer> map = new HashMap<>();
        Queue<String> queue = new LinkedList<>();
        Set<String> set = new HashSet<>();
        
        int step = 0;
        queue.offer(end);
        set.add(end);
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                String crt = queue.poll();
                map.put(crt, step);
                if (crt.equals(start)) {
                    return map;
                }
                for (int idx = 0; idx < crt.length(); idx++) {
                    for (char c = 'a'; c <= 'z'; c++) {
                        String newStr = changeChar(crt, idx, c);
                        if (!dict.contains(newStr) && !newStr.equals(start)) {
                            continue;
                        }
                        if (!set.contains(newStr)) {
                            queue.offer(newStr);
                            set.add(newStr);
                        }
                    }
                }
            }
            step++;
        }
        return map;
    }
    
    private String changeChar(String crt, int idx, char c) {
        char[] chars = crt.toCharArray();
        chars[idx] = c;
        return new String(chars);
    }
}
原文地址:https://www.cnblogs.com/jasminemzy/p/7802171.html