LeetCode126. 單詞接龍 II
阿新 • • 發佈:2020-12-20
☆☆☆☆☆思路:本題是127題的進階版,需要將找到的最短路徑儲存下來。
方法1:BFS。在到達最短路徑所在的層時,記錄並輸出所有符合條件的路徑。
1.127題的佇列只儲存每一層的元素,本題中佇列需要儲存每層新增元素之後的結果。
2. 如果該層新增的某一個單詞符合目標單詞,則該路徑為最短路徑,該層為最短路徑所在的層,但此時不能直接返回結果,必須將該層遍歷完,將該層所有符合的結果都新增進結果集;
3.每層新增單詞的時候,不能直接新增到總的已訪問單詞集合中,需要每層有一個單獨的該層訪問的單詞集,該層結束之後,再會合到總的已訪問單詞集合中,原因就是因為2
舉例:該層遇到目標單詞,有兩條路徑都可以遇到,但是先到達的將該單詞新增進 visited 中,會導致第二條路徑無法新增。
方法2:雙向BFS + DFS
程式碼1:BFS(耗時390ms)
class Solution { public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) { Set<String> dictSet = new HashSet<>(wordList); List<List<String>> res = new ArrayList<>();if (dictSet.size() == 0 || !dictSet.contains(endWord)) { return res; } // 累積每一層的結果佇列 Queue<List<String>> queue = new LinkedList<>(); Set<String> visited = new HashSet<>(); List<String> list = new ArrayList<>(Arrays.asList(beginWord)); queue.offer(list); visited.add(beginWord);// 是否到達符合條件的層:如果該層新增的某一單詞符合目標單詞,則說明截止該層的所有解為最短路徑,停止迴圈 boolean isFound = false; while (!queue.isEmpty() && !isFound) { // 上一層的結果佇列 int size = queue.size(); // 該層新增的所有元素:每層必須在所有結果都新增完新的單詞之後,再將這些單詞統一新增到已使用單詞集合 // 如果直接新增到 visited 中,會導致該層本次結果新增之後的相同新增行為失敗 Set<String> subVisited = new HashSet<>(); for (int i = 0; i < size; i++) { List<String> path = queue.poll(); // 獲取該路徑上一層的單詞 String cur = path.get(path.size() - 1); char[] chars = cur.toCharArray(); for (int j = 0; j < cur.length(); j++) { char temp = chars[j]; for (char k = 'a'; k <= 'z'; k++) { if (k == temp) continue; chars[j] = k; String newWord = String.valueOf(chars); // 符合條件:在 wordList 中 && 之前的層沒有使用過 if (dictSet.contains(newWord) && !visited.contains(newWord)) { // 生成新的路徑 List<String> pathList = new ArrayList<>(path); pathList.add(newWord); if (newWord.equals(endWord)) { isFound = true; res.add(pathList); } // 將該路徑新增到該層佇列中 queue.offer(pathList); // 將該單詞新增到該層已訪問的單詞集合中 subVisited.add(newWord); } } chars[j] = temp; } } // 將該層所有訪問的單詞新增到總的已訪問集合中 visited.addAll(subVisited); } return res; } }
程式碼2:雙向BFS + DFS
M
參考: