Word Ladder(双向BFS)

2018-10-02 23:46:38

问题描述:

问题求解:

显然是个解空间遍历问题,每次修改其中一位,由于步长是1,所以可以使用BFS进行解空间的遍历。

解法一、单向BFS

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> set = new HashSet<>();
        for(String i : wordList) set.add(i);
        if (!set.contains(endWord)) return 0;
        if (beginWord.equals(endWord)) return 1;
        Queue<String> queue = new LinkedList<>();
        Set<String> used = new HashSet<>();
        int step = 0;
        queue.add(beginWord);
        used.add(beginWord);
        while(!queue.isEmpty()) {
            int size = queue.size();
            step++;
            for (int i = 0; i < size; i++) {
                char[] chs = queue.poll().toCharArray();
                for (int j = 0; j < chs.length; j++) {
                    char ch = chs[j];
                    for (char c = 'a'; c <= 'z'; c++) {
                        if (c == ch) continue;
                        chs[j] = c;
                        String then = new String(chs);
                        if (then.equals(endWord)) return step + 1;
                        if (!set.contains(then) || used.contains(then)) continue;
                        queue.add(then);
                        used.add(then);
                    }
                    chs[j] = ch;
                }
            }
        }
        return 0;
    }

这里有个简单的优化,就是不使用used数组,而是每次使用扩展一个数前,将其从set中去除来防止再次扩展这个数。

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> set = new HashSet<>();
        for(String i : wordList) set.add(i);
        if (!set.contains(endWord)) return 0;
        if (beginWord.equals(endWord)) return 1;
        Queue<String> queue = new LinkedList<>();
        int step = 0;
        queue.add(beginWord);
        while(!queue.isEmpty()) {
            int size = queue.size();
            step++;
            for (int i = 0; i < size; i++) {
                char[] chs = queue.poll().toCharArray();
                for (int j = 0; j < chs.length; j++) {
                    char ch = chs[j];
                    for (char c = 'a'; c <= 'z'; c++) {
                        if (c == ch) continue;
                        chs[j] = c;
                        String then = new String(chs);
                        if (then.equals(endWord)) return step + 1;
                        if (!set.contains(then)) continue;
                        set.remove(then);
                        queue.add(then);
                    }
                    chs[j] = ch;
                }
            }
        }
        return 0;
    }

 

解法二、双向BFS

单向的BFS是可以通过所有的用例的,但是本题中解空间还是比较庞大的,可以使用双向BFS来进一步的提高算法的时间复杂度。

从两边开始遍历,每次遍历一端,所以需要维护两个Set,这里不用Queue是为了方便实现。

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> set = new HashSet<>();
        for(String i : wordList) set.add(i);
        if (!set.contains(endWord)) return 0;
        if (beginWord.equals(endWord)) return 1;
        Set<String> q1 = new HashSet<>();
        Set<String> q2 = new HashSet<>();
        q1.add(beginWord);
        q2.add(endWord);
        int step = 0;
        while (!q1.isEmpty() && !q2.isEmpty()) {
            step++;
            if (q1.size() > q2.size()) {
                Set<String> tmp = q1;
                q1 = q2;
                q2 = tmp;
            }
            Set<String> cur = new HashSet<>();
            for (String w : q1) {
                char[] chs = w.toCharArray();
                for (int i = 0; i < chs.length; i++) {
                    char ch = chs[i];
                    for (char c = 'a'; c <= 'z'; c++) {
                        if (c == ch) continue;
                        chs[i] = c;
                        String then = new String(chs);
                        if (q2.contains(then)) return step + 1;
                        if (!set.contains(then)) continue;
                        set.remove(then);
                        cur.add(then);
                    }
                    chs[i] = ch;
                }
            }
            q1 = cur;
        }
        return 0;
    }

 

posted @ 2018-10-03 00:54  hyserendipity  阅读(575)  评论(0编辑  收藏  举报