126.word-ladder-ii-TLE.java 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import java.util.*;
  2. class Solution {
  3. private int min;
  4. public List<List<String>> findLadders(String beginWord, String endWord, List<String> wordList) {
  5. List<List<String>> res = new ArrayList<>();
  6. int begIdx = -1, endIdx = -1;
  7. for (int i = 0; i < wordList.size(); i++) {
  8. String word = wordList.get(i);
  9. if (word.equals(beginWord)) begIdx = i;
  10. if (word.equals(endWord)) endIdx = i;
  11. }
  12. if (begIdx == -1) begIdx = wordList.size();
  13. if (endIdx == -1) return res;
  14. // Create adj matrix
  15. int n = Math.max(wordList.size(), begIdx + 1);
  16. List<List<Integer>> adj = new ArrayList<>();
  17. for (int i = 0; i < n; i++) adj.add(new ArrayList<>());
  18. for (int i = 0; i < n; i++) {
  19. List<Integer> li = adj.get(i);
  20. String w1 = i == begIdx ? beginWord : wordList.get(i);
  21. for (int j = 0; j < wordList.size(); j++) {
  22. String w2 = wordList.get(j);
  23. if (isConvertible(w1, w2)) li.add(j);
  24. }
  25. }
  26. // Init path
  27. min = Integer.MAX_VALUE;
  28. List<String> path = new ArrayList<>();
  29. path.add(beginWord);
  30. boolean[] used = new boolean[wordList.size()];
  31. if (begIdx < wordList.size()) used[begIdx] = true;
  32. dfs(adj, wordList, res, path, used, begIdx, endIdx);
  33. return res;
  34. }
  35. private boolean isConvertible(String w1, String w2) {
  36. int cnt = 0;
  37. for (int i = 0; i < w1.length(); i++) {
  38. if (w1.charAt(i) != w2.charAt(i)) cnt++;
  39. }
  40. return cnt == 1;
  41. }
  42. private void dfs(List<List<Integer>> adj, List<String> words, List<List<String>> res, List<String> path, boolean[] used, int idx, int endIdx) {
  43. if (min < path.size()) return;
  44. if (idx == endIdx) {
  45. if (path.size() < min) {
  46. res.clear();
  47. min = path.size();
  48. }
  49. List<String> copy = new ArrayList<>();
  50. copy.addAll(path);
  51. res.add(copy);
  52. return;
  53. }
  54. List<Integer> li = adj.get(idx);
  55. for (Integer next : li) {
  56. if (used[next]) continue;
  57. used[next] = true;
  58. path.add(words.get(next));
  59. dfs(adj, words, res, path, used, next, endIdx);
  60. used[next] = false;
  61. path.remove(path.size() - 1);
  62. }
  63. }
  64. }