邓心一 vor 6 Jahren
Ursprung
Commit
72e512b329
2 geänderte Dateien mit 116 neuen und 45 gelöschten Zeilen
  1. 68 0
      hard/126.word-ladder-ii-TLE.java
  2. 48 45
      hard/126.word-ladder-ii.java

+ 68 - 0
hard/126.word-ladder-ii-TLE.java

@@ -0,0 +1,68 @@
+import java.util.*;
+
+class Solution {
+    private int min;
+
+    public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
+        List<List<String>> res = new ArrayList<>();
+        int begIdx = -1, endIdx = -1;
+        for (int i = 0; i < wordList.size(); i++) {
+            String word = wordList.get(i);
+            if (word.equals(beginWord)) begIdx = i;
+            if (word.equals(endWord)) endIdx = i;
+        }
+        if (begIdx == -1) begIdx = wordList.size();
+        if (endIdx == -1) return res;
+        // Create adj matrix
+        int n = Math.max(wordList.size(), begIdx + 1);
+        List<List<Integer>> adj = new ArrayList<>();
+        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
+        for (int i = 0; i < n; i++) {
+            List<Integer> li = adj.get(i);
+            String w1 = i == begIdx ? beginWord : wordList.get(i);
+            for (int j = 0; j < wordList.size(); j++) {
+                String w2 = wordList.get(j);
+                if (isConvertible(w1, w2)) li.add(j);
+            }
+        }
+        // Init path
+        min = Integer.MAX_VALUE;
+        List<String> path = new ArrayList<>();
+        path.add(beginWord);
+        boolean[] used = new boolean[wordList.size()];
+        if (begIdx < wordList.size()) used[begIdx] = true;
+        dfs(adj, wordList, res, path, used, begIdx, endIdx);
+        return res;
+    }
+
+    private boolean isConvertible(String w1, String w2) {
+        int cnt = 0;
+        for (int i = 0; i < w1.length(); i++) {
+            if (w1.charAt(i) != w2.charAt(i)) cnt++;
+        }
+        return cnt == 1;
+    }
+
+    private void dfs(List<List<Integer>> adj, List<String> words, List<List<String>> res, List<String> path, boolean[] used, int idx, int endIdx) {
+        if (min < path.size()) return;
+        if (idx == endIdx) {
+            if (path.size() < min) {
+                res.clear();
+                min = path.size();
+            }
+            List<String> copy = new ArrayList<>();
+            copy.addAll(path);
+            res.add(copy);
+            return;
+        }
+        List<Integer> li = adj.get(idx);
+        for (Integer next : li) {
+            if (used[next]) continue;
+            used[next] = true;
+            path.add(words.get(next));
+            dfs(adj, words, res, path, used, next, endIdx);
+            used[next] = false;
+            path.remove(path.size() - 1);
+        }
+    }
+}

+ 48 - 45
hard/126.word-ladder-ii.java

@@ -1,40 +1,66 @@
 import java.util.*;
 
 class Solution {
-    private int min;
+    private List<List<String>> res;
+    private List<List<Integer>> prev;
+    private List<String> wordList;
+    private String beginWord;
 
     public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
-        List<List<String>> res = new ArrayList<>();
-        int begIdx = -1, endIdx = -1;
+        res = new ArrayList<>();
+        prev = new ArrayList<>();
+        this.wordList = wordList;
+        this.beginWord = beginWord;
+        int[] dist = new int[wordList.size()];
+        boolean[] used = new boolean[wordList.size()];
+        int endIdx = -1;
+        List<Integer> queue = new ArrayList<>();
         for (int i = 0; i < wordList.size(); i++) {
+            prev.add(new ArrayList<>());
             String word = wordList.get(i);
-            if (word.equals(beginWord)) begIdx = i;
             if (word.equals(endWord)) endIdx = i;
+            if (isConvertible(beginWord, word)) {
+                used[i] = true;
+                prev.get(i).add(-1);
+                dist[i] = 1;
+                queue.add(i);
+            }
         }
-        if (begIdx == -1) begIdx = wordList.size();
         if (endIdx == -1) return res;
-        // Create adj matrix
-        int n = Math.max(wordList.size(), begIdx + 1);
-        List<List<Integer>> adj = new ArrayList<>();
-        for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
-        for (int i = 0; i < n; i++) {
-            List<Integer> li = adj.get(i);
-            String w1 = i == begIdx ? beginWord : wordList.get(i);
-            for (int j = 0; j < wordList.size(); j++) {
-                String w2 = wordList.get(j);
-                if (isConvertible(w1, w2)) li.add(j);
+        while (!queue.isEmpty()) {
+            List<Integer> newQueue = new ArrayList<>();
+            for (Integer i : queue) {
+                for (int j = 0; j < wordList.size(); j++) {
+                    if (used[j]) continue;
+                    if (!isConvertible(wordList.get(i), wordList.get(j))) continue;
+                    prev.get(j).add(i);
+                    if (dist[j] != 0) continue;
+                    dist[j] = dist[i] + 1;
+                    newQueue.add(j);
+                }
             }
+            queue = newQueue;
+            for (Integer i : queue) used[i] = true;
         }
-        // Init path
-        min = Integer.MAX_VALUE;
-        List<String> path = new ArrayList<>();
-        path.add(beginWord);
-        boolean[] used = new boolean[wordList.size()];
-        if (begIdx < wordList.size()) used[begIdx] = true;
-        dfs(adj, wordList, res, path, used, begIdx, endIdx);
+        dfs(endIdx, new ArrayList<String>());
         return res;
     }
 
+    private void dfs(int idx, List<String> path) {
+        List<String> newPath = new ArrayList<>();
+        if (idx == -1) {
+            newPath.add(beginWord);
+            newPath.addAll(path);
+            res.add(newPath);
+            return;
+        }
+        newPath.add(wordList.get(idx));
+        newPath.addAll(path);
+        for (Integer i : prev.get(idx)) {
+            dfs(i, newPath);
+        }
+    }
+
     private boolean isConvertible(String w1, String w2) {
         int cnt = 0;
         for (int i = 0; i < w1.length(); i++) {
@@ -42,27 +68,4 @@ class Solution {
         }
         return cnt == 1;
     }
-
-    private void dfs(List<List<Integer>> adj, List<String> words, List<List<String>> res, List<String> path, boolean[] used, int idx, int endIdx) {
-        if (min < path.size()) return;
-        if (idx == endIdx) {
-            if (path.size() < min) {
-                res.clear();
-                min = path.size();
-            }
-            List<String> copy = new ArrayList<>();
-            copy.addAll(path);
-            res.add(copy);
-            return;
-        }
-        List<Integer> li = adj.get(idx);
-        for (Integer next : li) {
-            if (used[next]) continue;
-            used[next] = true;
-            path.add(words.get(next));
-            dfs(adj, words, res, path, used, next, endIdx);
-            used[next] = false;
-            path.remove(path.size() - 1);
-        }
-    }
 }