[LintCode/LeetCode] Word Ladder II

351 查看

Problem

Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

Only one letter can be changed at a time
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"]
]

Note

  • result: 存放transformation过程中的所有List<String>集合

  • map: key为所有transformation的结尾String,value则顺序存放这个结尾String对应的transformation中的所有String

  • queue: 存放同一个循环level的新加入的String,在下一个循环再依次对其中元素进行进一步的BFS

  • preList: 把首个字符串start放入新List,再将List放入res,并将start-res键值对放入map,进行初始化

Solution

public class Solution {
    public List<List<String>> findLadders(String start, String end, Set<String> dict) {
        List<List<String>> res = new ArrayList<>();
        List<String> preList = new ArrayList<>();
        Queue<String> queue = new LinkedList<>();
        Map<String, List<List<String>>> map = new HashMap<>();
        preList.add(start);
        queue.offer(start);
        res.add(preList);
        map.put(start, res);
        while (!queue.isEmpty()) {
            String pre = queue.poll();
            if (pre.equals(end)) return map.get(pre);
            for (int i = 0; i < pre.length(); i++) {
                for (int j = 0; j < 26; j++) {
                    StringBuilder sb = new StringBuilder(pre);
                    sb.setCharAt(i,(char) ('a'+j));
                    String cur = sb.toString();
                    if (!cur.equals(pre) && dict.contains(cur) && (!map.containsKey(cur) || map.get(pre).get(0).size()+1 <= map.get(cur).get(0).size())) {
                        List<List<String>> temp = new ArrayList<>();
                        for (List<String> p: map.get(pre)) {
                            List<String> curList = new ArrayList<>(p);
                            curList.add(cur);
                            temp.add(curList);
                        }
                        if (!map.containsKey(cur)) {
                            map.put(cur, temp);
                            queue.offer(cur);
                        }
                        else if (map.get(pre).get(0).size()+1 < map.get(cur).get(0).size()) map.put(cur, temp);
                        else map.get(cur).addAll(temp);
                        
                    }
                }
            }
        }
        return res.get(0).size() > 1 ? res : new ArrayList<List<String>>();
    }
}