JAVA:
public final List<String> findLadders(String beginWord, String endWord, List<String> wordList) { List<String> re = new LinkedList<String>(); Set<String> set = new HashSet<>(), his = new HashSet<>(); boolean exit = dfs(re, set, his, beginWord, endWord, wordList); if (exit) re.add(0, beginWord); return re; } private final boolean dfs(List<String> re, Set<String> set, Set<String> his, String curr, String endWord, List<String> wordList) { for (int i = 0; i < wordList.size(); i++) { String next = wordList.get(i); if (set.contains(next) || !this.canBeNext(curr, next) || his.contains(curr)) continue; set.add(next); re.add(next); if (next.equals(endWord) || dfs(re, set, his, next, endWord, wordList)) return true; set.remove(next); re.remove(re.size() - 1); his.add(next); } return false; } private final boolean canBeNext(String pre, String next) { int len = pre.length(), diff = 0; for (int i = 0; i < len; i++) { if (pre.charAt(i) != next.charAt(i)) { if (diff == 0) diff++; else return false; } } return diff == 0 ? false : true; }
JS:
/** * @param {string} beginWord * @param {string} endWord * @param {string[]} wordList * @return {string[]} */ var findLadders = function (beginWord, endWord, wordList) { let re = []; let hasRe = dfs(re, beginWord, new Set(), new Set(), endWord, wordList); if (hasRe) re.unshift(beginWord); return re; }; var dfs = function (re, curr, set, his, endWord, wordList) { for (let i = 0; i < wordList.length; i++) { let next = wordList[i]; if (set.has(next) || his.has(next) || !canBeNext(curr, next)) continue set.add(next); his.add(next); re.push(next); if (next == endWord || dfs(re, next, set, his, endWord, wordList)) return true; set.delete(next); re.pop(); } return false; } var canBeNext = function (pre, next) { if (!pre || !next) return false; let len = pre.length, diff = 0; for (let i = 0; i < len; i++) { if (pre.charAt(i) != next.charAt(i)) { if (diff == 0) diff++; else return false; } } return diff == 1; }