资讯专栏INFORMATION COLUMN

[LeetCode] 126. Word Ladder II

wayneli / 1766人阅读

摘要:存放过程中的所有集合为所有的结尾,则顺序存放这个结尾对应的中的所有存放同一个循环的新加入的,在下一个循环再依次对其中元素进行进一步的把首个字符串放入新,再将放入,并将键值对放入,进行初始化

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

Solution DFS+BFS Updated 2018-11
class Solution {
    public List> findLadders(String start, String end, List wordList) {
        List> res = new ArrayList<>();
        Set dict = new HashSet<>(wordList);
        if (!dict.contains(end)) return res;
        //save shortest distance from start to each node
        Map distanceMap = new HashMap<>();
        //save all the nodes can be transformed from each node
        Map> neighborMap = new HashMap<>();
        
        dict.add(start);
        //use bfs to: find the shortest distance; update neighborMap and distanceMap
        bfs(start, end, dict, neighborMap, distanceMap);
        //use dfs to: output all the paths with the shortest distance
        dfs(start, end, neighborMap, distanceMap, new ArrayList<>(), res);
        
        return res;
    }
    
    private void bfs(String start, String end, Set dict, Map> neighborMap, Map distanceMap) {
        for (String str: dict) {
            neighborMap.put(str, new ArrayList<>());
        }
        
        Deque queue = new ArrayDeque<>();
        queue.offer(start);
        distanceMap.put(start, 0);
        
        while (!queue.isEmpty()) {
            int size = queue.size();
            boolean foundEnd = false;
            for (int i = 0; i < size; i++) {
                String cur = queue.poll();
                int curDist = distanceMap.get(cur);
                List neighbors = getNeighbors(dict, cur);
                
                for (String neighbor: neighbors) {
                    neighborMap.get(cur).add(neighbor);
                    if (!distanceMap.containsKey(neighbor)) {
                        distanceMap.put(neighbor, curDist+1);
                        if (neighbor.equals(end)) foundEnd = true;
                        else queue.offer(neighbor);
                    }
                }
            }
            if (foundEnd) break;
        }
    }
    
    private void dfs(String start, String end, Map> neighborMap, Map distanceMap, List temp, List> res) {
        if (start.equals(end)) {
            temp.add(start);
            res.add(new ArrayList<>(temp));
            temp.remove(temp.size()-1);
        }
        for (String neighbor: neighborMap.get(start)) {
            temp.add(start);
            if (distanceMap.get(neighbor) == distanceMap.get(start)+1) {
                dfs(neighbor, end, neighborMap, distanceMap, temp, res);
            }
            temp.remove(temp.size()-1);
        }
    }
    
    private List getNeighbors(Set dict, String str) {
        List res = new ArrayList<>();
        for (int i = 0; i < str.length(); i++) {
            StringBuilder sb = new StringBuilder(str);
            for (char ch = "a"; ch <= "z"; ch++) {
                sb.setCharAt(i, ch);
                String neighbor = sb.toString();
                if (dict.contains(neighbor)) res.add(neighbor);
            }
        }
        return res;
    }
}
Solution Note

result: 存放transformation过程中的所有List集合

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

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

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

public class Solution {
    public List> findLadders(String start, String end, Set dict) {
        List> res = new ArrayList<>();
        List preList = new ArrayList<>();
        Queue queue = new LinkedList<>();
        Map>> 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> temp = new ArrayList<>();
                        for (List p: map.get(pre)) {
                            List 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>();
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/65014.html

相关文章

  • leetcode126. Word Ladder II

    摘要:题目要求相比于,要求返回所有的最短路径。至于如何生成该有向图,则需要通过广度优先算法,利用队列来实现。将每一层的分别入栈。如果遇到则至该层结尾广度优先算法结束。通过这种方式来防止形成圈。 题目要求 Given two words (beginWord and endWord), and a dictionarys word list, find all shortest transfo...

    cooxer 评论0 收藏0
  • 126. Word Ladder II

    题目:Given two words (beginWord and endWord), and a dictionarys word list, find all shortest transformation sequence(s) from beginWord to endWord, such that: Only one letter can be changed at a timeEach...

    Tangpj 评论0 收藏0
  • [Leetcode] Word Ladder 单词爬梯

    摘要:另外,为了避免产生环路和重复计算,我们找到一个存在于字典的新的词时,就要把它从字典中移去。代码用来记录跳数控制来确保一次循环只计算同一层的节点,有点像二叉树遍历循环这个词从第一位字母到最后一位字母循环这一位被替换成个其他字母的情况 Word Ladder Given two words (beginWord and endWord), and a dictionary, find t...

    pinecone 评论0 收藏0
  • leetcode127. Word Ladder

    摘要:但是这种要遍历所有的情况,哪怕是已经超过最小操作次数的情况,导致代码超时。其实从另一个角度来说,这道题可以看做是广度优先算法的一个展示。按上文中的题目为例,可以将广度优先算法写成以下形式。 题目要求 Given two words (beginWord and endWord), and a dictionarys word list, find the length of short...

    Galence 评论0 收藏0
  • [LeetCode/LintCode] Word Ladder

    摘要:使用,利用其按层次操作的性质,可以得到最优解。这样可以保证这一层被完全遍历。每次循环取出的元素存为新的字符串。一旦找到和相同的字符串,就返回转换序列长度操作层数,即。 Problem Given two words (start and end), and a dictionary, find the length of shortest transformation sequence...

    张金宝 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<