「力扣」第 127 题:单词接龙(BFS)

考虑使用位运算压缩的做法。

Java 代码:

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

public class Solution {
    
    

    // 推荐的,固定模式的写法

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    
    
        // wordList 中如果有 beginWord 应该删除,用哈希表便于查找和修改
        Set<String> hashSet = new HashSet<>(wordList);
        hashSet.remove(beginWord);

        // BFS 必须使用队列
        Queue<String> queue = new LinkedList<>();
        queue.offer(beginWord);

        int step = 1;
        while (!queue.isEmpty()) {
    
    
            int currentSize = queue.size();

            for (int i = 0; i < currentSize; i++) {
    
    
                // 依次遍历当前队列中的单词
                String word = queue.poll();

                int len = word.length();
                char[] charArray = word.toCharArray();

                // 修改每一个字符
                for (int j = 0; j < len; j++) {
    
    
                    // 一轮以后应该重置,否则结果不正确
                    char currentChar = charArray[j];

                    for (char k = 'a'; k <= 'z'; k++) {
    
    
                        charArray[j] = k;
                        String temp = String.valueOf(charArray);

                        if (hashSet.contains(temp)) {
    
    
                            if (temp.equals(endWord)) {
    
    
                                return step + 1;
                            }
                            queue.add(temp);

                            // 找到了以后,下一次就不是目标了,所以要删除
                            hashSet.remove(temp);
                        }
                    }

                    // 恢复,下次再用
                    charArray[j] = currentChar;
                }
            }
            step++;
        }
        return 0;
    }
}

下面这两种写法都是把层数封装在一起写的,非标准写法。

Java 代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

public class Solution {
    
    
    
    // 非标准 BFS 的写法

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    
    
        Queue<Pair> queue = new LinkedList<>();
        queue.offer(new Pair(beginWord, 1));
        Set<String> visited = new HashSet<>();
        visited.add(beginWord);

        
        while (!queue.isEmpty()) {
    
    
            Pair curPair = queue.poll();
            String curWord = curPair.word;
            Integer step = curPair.step;

            step++;
            List<String> nextWords = onlyChangeOne(curWord, wordList, visited);
            for (String nextWord : nextWords) {
    
    
                if (nextWord.equals(endWord)) {
    
    
                    return step;
                }
                queue.offer(new Pair(nextWord, step));
                visited.add(nextWord);
            }
        }
        return 0;
    }


    private List<String> onlyChangeOne(String word, List<String> wordList, Set<String> visited) {
    
    
        // 与 word 相差一个字母的 wordList 的元素有哪些,并且要保证没有使用过
        List<String> res = new ArrayList<>();

        int len = word.length();
        for (String match : wordList) {
    
    
            int count = 0;
            for (int i = 0; i < len; i++) {
    
    
                if (word.charAt(i) != match.charAt(i)) {
    
    
                    count++;
                    // 如果不同的字母的数量已经大于 1 个,那么它就肯定不是我们要找的单词
                    if (count >= 2) {
    
    
                        break;
                    }
                }
            }

            // 恰好相差一个字符,且还未被访问过,才是邻居
            if (count == 1 && !visited.contains(match)) {
    
    
                res.add(match);
            }
        }
        return res;
    }


    private class Pair {
    
    
        private String word;
        private Integer step;

        public Pair(String word, Integer step) {
    
    
            this.word = word;
            this.step = step;
        }
    }


    public static void main(String[] args) {
    
    
        List<String> wordList = new ArrayList<>();
        String[] words = {
    
    "hot", "dot", "dog", "lot", "log", "cog"};
        Collections.addAll(wordList, words);

        Solution solution = new Solution();
        String beginWord = "hit";
        String endWord = "cog";
        int ladderLength = solution.ladderLength(beginWord, endWord, wordList);
        System.out.println(String.format("从 %s 到 %s 的最短转换序列的长度:%d。", beginWord, endWord, ladderLength));
    }
}

Java 代码:

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

public class Solution {
    
    

    // 这种写法 map 很累赘,不推荐

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    
    
        // wordList 中如果有 beginWord 应该删除
        Set<String> set = new HashSet<>(wordList);
        set.remove(beginWord);

        // BFS 必须使用队列
        Queue<String> queue = new LinkedList<>();
        queue.offer(beginWord);

        Map<String, Integer> map = new HashMap<>();
        map.put(beginWord, 1);

        while (!queue.isEmpty()) {
    
    
            // 从队列首出队
            String word = queue.poll();
            int curStep = map.get(word);
            for (int i = 0; i < word.length(); i++) {
    
    
                char[] charArray = word.toCharArray();
                for (char j = 'a'; j <= 'z'; j++) {
    
    
                    charArray[i] = j;
                    String temp = new String(charArray);
                    if (set.contains(temp)) {
    
    
                        if (temp.equals(endWord)) {
    
    
                            return curStep + 1;
                        }
                        map.put(temp, curStep + 1);
                        queue.offer(temp);
                        set.remove(temp);
                    }
                }
            }
        }
        return 0;
    }
}

没看懂的做法:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

public class Solution {
    
    

    // 编码太复杂,不推荐

    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    
    
        int len = beginWord.length();

        Map<String, ArrayList<String>> allComboDict = new HashMap<>();

        for (String s : wordList) {
    
    
            for (int i = 0; i < len; i++) {
    
    
                // 得到这个单词所有的模式
                String newWord = s.substring(0, i) + '*' + s.substring(i + 1, len);
                ArrayList<String> transformations = allComboDict.getOrDefault(newWord, new ArrayList<>());
                transformations.add(s);

                allComboDict.put(newWord, transformations);
            }
        }

        // 预处理
        Set<Map.Entry<String, ArrayList<String>>> entries = allComboDict.entrySet();
        for (Map.Entry<String, ArrayList<String>> map : entries) {
    
    
            System.out.println(map.getKey() + " " + map.getValue());
        }

        Queue<Pair<String, Integer>> queue = new LinkedList<>();
        queue.add(new Pair<>(beginWord, 1));

        Map<String, Boolean> visited = new HashMap<>();
        visited.put(beginWord, true);

        while (!queue.isEmpty()) {
    
    
            Pair<String, Integer> node = queue.poll();

            String word = node.getKey();
            int level = node.getValue();

            for (int i = 0; i < len; i++) {
    
    
                // 拿出这个单词所有的模式
                String newWord = word.substring(0, i) + '*' + word.substring(i + 1, len);

                for (String adjacentWord : allComboDict.getOrDefault(newWord, new ArrayList<String>())) {
    
    
                    if (adjacentWord.equals(endWord)) {
    
    
                        return level + 1;
                    }

                    if (!visited.containsKey(adjacentWord)) {
    
    
                        visited.put(adjacentWord, true);
                        queue.add(new Pair<>(adjacentWord, level + 1));
                    }
                }
            }
        }
        return 0;
    }

    private class Pair<K, V> {
    
    
        private K key;
        private V value;

        public Pair(K key, V value) {
    
    
            this.key = key;
            this.value = value;
        }

        public K getKey() {
    
    
            return key;
        }

        public V getValue() {
    
    
            return value;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/lw_power/article/details/106475641