Word Ladder II

Word Ladder II

  Total Accepted: 1864  Total Submissions: 22064 My Submissions

 

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

For example,

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

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

 

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

和 I 类似,还是要BFS, 但这次要储存路径,用一个二维数组先储存BFS每一层的String, 然后再DFS数组,找出路径。

例如 :

Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]

Return

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

 

BFS 每层的String分别为:

[hit]

[hot]

[lot, dot]

[log, dog]

[cog]

 

这道题其实可以把所有的单词转换成一个无向图中的节点,算出每个节点的邻居,然后用 Dijkstra算法算出最短路径就可以了。




    public static ArrayList<ArrayList<String>> findLadders(String start, String end, HashSet<String> dict){
        Map<String, Integer> map = new HashMap<>();
        Map<String, Set<String>> preWordMap = new HashMap<>();
        map.put(start, 0);
        Queue<String> queue = new LinkedList<>();
        queue.add(start);
        Set<String> visit = new HashSet<>();
        while (!queue.isEmpty()) {
            String s = queue.poll();
            if (visit.contains(s))
                continue;
            visit.add(s);
            Set<String> set = strList(s, dict);
            for (String str : set) {
                queue.add(str);
                int count = map.get(s);
                if (map.get(str)==null || map.get(str)==count+1){
                    map.put(str, count + 1);
                    if(preWordMap.get(str) == null){
                        Set<String> subSet = new HashSet<>();
                        subSet.add(s);
                        preWordMap.put(str,subSet);
                    }else{
                        Set<String> subSet = preWordMap.get(str);
                        subSet.add(s);
                        preWordMap.put(str,subSet);
                    }
                }
            }
        }

        int min = Integer.MAX_VALUE;
        Set<String> resultSet = new HashSet<>();
        Set<String> endSet = strList(end, dict);
        for (String s : endSet) {
            int i = map.get(s);
            if (i < min){
                resultSet.clear();
                resultSet.add(s);
                min = i;
            }else if (i== min){
                resultSet.add(s);
            }
        }
        preWordMap.put(end,resultSet);

        ArrayList<ArrayList<String>> list = new ArrayList<>();
        ArrayList<String> l = new ArrayList<>();
        helper(end, end, preWordMap, list, l);

        return list;

    }

    private static void helper(String str,String end, Map<String,Set<String>> preWordMap, ArrayList<ArrayList<String>> list, ArrayList<String> l){
        Set<String> set = preWordMap.get(str);
        if(set == null){
            ArrayList<String> newList = new ArrayList<>(l);
            Collections.reverse(newList);
            newList.add(end);
            list.add(newList);
            return;
        }
        for(String s: set){
            l.add(s);
            helper(s,end,preWordMap,list,l);
            l.remove(l.size()-1);
        }
    }




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值