[刷题]Word Ladder II

[LintCode]Word Ladder II

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) {
        List<List<String>> rst = new ArrayList<List<String>>();
        /**
         * 各个点的连接情况
         * 每个点的上面都有哪些点
         */
        Map<String, List<String>> map = new HashMap<String, List<String>>();
        /**
         * 每一个点到起点的最短距离 
         */
        Map<String, Integer> distance = new HashMap<String, Integer>();


        dict.add(start);
        dict.add(end);
 
        bfs(map, distance, start, end, dict);
        
        List<String> path = new ArrayList<String>();
        
        path.add(end); // 先在路径中加上终点
        dfs(rst, path, end, start, distance, map);


        return rst;
    }
    
    
    /**
     * 通过map distance找出所有最短路径
     * 从 终点 向 起点 找
     */
    void dfs(List<List<String>> rst, List<String> path, String crt,
            String start, Map<String, Integer> distance,
            Map<String, List<String>> map) {
        
        // 递归的退出条件
        if (crt.equals(start)) {
            Collections.reverse(path);
            rst.add(new ArrayList<String>(path)); // 找到一个最短路径
            Collections.reverse(path);
            return;
        }
        
        // 遍历crt上面的点
        for (String next : map.get(crt)) {
            if (distance.containsKey(next) && distance.get(crt) == distance.get(next) + 1) { 
                // 这是一个正确的方向,继续向上找
                path.add(next); // 从 终点 向 起点
                dfs(rst, path, next, start, distance, map);
                path.remove(path.size() - 1);
            }
        }           
        
    }


    /**
     * 广度优先搜索
     * 从上至下遍历
     * 填充 map distance
     */
    void bfs(Map<String, List<String>> map, Map<String, Integer> distance,
            String start, String end, Set<String> dict) {
        Queue<String> queue = new ArrayDeque<String>();
        queue.offer(start);
        distance.put(start, 0);
        for (String s : dict) {
            // dict中的每一个词都对应一个数组
            map.put(s, new ArrayList<String>());
        }
        
        // 从上至下层序遍历
        while (!queue.isEmpty()) {
            String crt = queue.poll(); // 不会重复遍历相同的crt


            List<String> nextList = expand(crt, dict);
            for (String next : nextList) {
                map.get(next).add(crt); //填充map
                if (!distance.containsKey(next)) {
                    // 填充distance,这个点到起点的最短路径
                    distance.put(next, distance.get(crt) + 1); 
                    queue.offer(next); // 遍历过的点不会再被遍历
                }
            }
        }
    }


    /**
     * 返回一个数组,数组元素为String
     * 这个数组包含了crt的所有可能的拓展
     * 该数组中所有的元素都必须是dict中的元素
     */
    List<String> expand(String crt, Set<String> dict) {
        List<String> expansion = new ArrayList<String>();


        for (int i = 0; i < crt.length(); i++) {
            for (char ch = 'a'; ch <= 'z'; ch++) {
                if (ch != crt.charAt(i)) {
                    String expanded = crt.substring(0, i) + ch
                            + crt.substring(i + 1);
                    if (dict.contains(expanded)) {
                        expansion.add(expanded); // 放入数组
                    }
                }
            }
        }


        return expansion;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值