class Solution {
int ladder = Integer.MAX_VALUE;
List<String> path = new ArrayList<String>();
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
dfs(beginWord, endWord, wordList, 0);
if(ladder < Integer.MAX_VALUE) return ladder;
else return 0;
}
void dfs(String beginWord, String endWord, List<String> wordList, int count){
if(beginWord.compareTo(endWord) == 0){
if(count+1 < ladder) {
ladder = count+1;
for(int x = 0; x < path.size(); x++)
System.out.print(";"+ path.get(x));
}
System.out.println();
return;
}
for(int i = 0; i < beginWord.length(); i ++){
int j = 0;
while(j < wordList.size()){
StringBuilder temp = new StringBuilder();
for(int x = 0; x < beginWord.length(); x ++){
temp.append(beginWord.charAt(x));
}
j = change(temp,wordList,i,j); // i is the character in word will be changed, j is the start searching index of wordList
if(j == 0)
break;
String begin = new String(temp);
// System.out.println("begin="+ begin);
path.add(begin);
dfs(begin, endWord, wordList, count+1);
path.remove(path.size()-1);
}
}
}
int change(StringBuilder temp, List<String> wordList, int i,int j){
// System.out.println("enter change temp = "+ temp);
char ch = temp.charAt(i);
String alph = new String("abcdefghijklmnopqrstuvwxyz");
for(int x = 0; x < 26; x++){
if(ch == alph.charAt(x)) {
continue;
}
temp.setCharAt(i, alph.charAt(x));
if(wordList.contains(new String(temp)) && !path.contains(new String(temp)) && wordList.indexOf(new String(temp)) >= j){
// System.out.println("new temp="+temp);
return wordList.indexOf(new String(temp))+1;
}
}
// for(int x = j; x < wordList.size(); x ++){
// if(path.contains(wordList.get(x))) continue;
// boolean flag1 = true, flag2 = true;
// for(int y = 0; y < temp.length(); y ++){
// if(y == i && temp.charAt(i) == wordList.get(x).charAt(y)) {
// flag1 = false;
// break;
// }
// if(y != i && temp.charAt(y) != wordList.get(x).charAt(y)){
// flag2 = false;
// break;
// }
// }
// //System.out.println("worldList=" + wordList.get(x));
// if(flag1 && flag2){
// // System.out.println("enter true");
// temp.setCharAt(i, wordList.get(x).charAt(i));
// // System.out.println("intend change word to=" + wordList.get(x));
// // System.out.println("temp =" + temp);
// return x+1;
// }
// }
return 0;
}
}
Solution 3(fail to handle big N but is better than solution 1 & 2)
class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
Queue<String> que = new LinkedList<String>();
int ladder = 1;
if(!wordList.contains(endWord)) return 0;
wordList.remove(endWord);
wordList.add(beginWord);
que.offer(endWord);
que.offer("#");
while(!que.isEmpty()){
String midWord = new String(que.poll());
System.out.println(midWord);
if(midWord.equals("#")){
if(!que.isEmpty()){
que.offer("#");
ladder ++;
}
continue;
}
int i = beginWord.length()-1; // ith character in midWord
while(i >= 0){
int j = -1; // jth word in wordList
while(j < wordList.size()){
j = change(wordList, midWord, i);
if(j == -1) break;
//System.out.println(j);
if(wordList.get(j).equals(beginWord)) return ladder+1;
System.out.println(wordList.get(j));
que.offer(wordList.get(j));
wordList.remove(wordList.get(j));
}
i --;
}
}
return 0;
}
int change(List<String> wordList, String midword, int i){
StringBuilder temp = new StringBuilder(midword);
String alp = "abcdefghijklmnopqrstuvwxyz";
char ch = temp.charAt(i);
for(int j = 0; j < 26; j ++){
if(alp.charAt(j) == ch) continue;
temp.setCharAt(i, alp.charAt(j));
//System.out.println(temp);
if(wordList.contains(new String(temp))){
return wordList.indexOf(new String(temp));
}
}
return -1;
}
}
Solution 5, BFS + hashMap(fail to handle large input, Python and Java)
class Solution {
Map<String, List<String>> map = new HashMap<>();
Map<String, List<String>> adjList = new HashMap<>();
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
if(!wordList.contains(endWord))
return 0;
if(wordList.contains(beginWord)) {
wordList.remove(beginWord);
}
createMap(beginWord, wordList);
System.out.println(map);
int shortest = createAdjList(beginWord, endWord);
return shortest;
}
private void createMap(String beginWord, List<String> wordList) {
List<String> nextWord = findNext(wordList, beginWord);
map.put(beginWord, nextWord);
for(int i = 0; i < wordList.size(); i ++) {
nextWord = findNext(wordList, wordList.get(i));
map.put(wordList.get(i), nextWord);
}
}
private List<String> findNext(List<String> wordList, String word) {
String letters = "abcdefghijklmnopqrstuvwxyz";
List<String> next = new ArrayList<>();
for(int i = 0; i < word.length(); i ++) {
for(int j = 0; j < letters.length(); j ++) {
String newWord = word.substring(0, i) + letters.charAt(j) + word.substring(i+1, word.length());
if(!newWord.equals(word) && wordList.contains(newWord))
next.add(newWord);
}
}
return next;
}
private int createAdjList(String beginWord, String endWord) {
Queue<String> q = new LinkedList<String>();
q.add(beginWord);
Map<String, Integer> visited = new HashMap<String, Integer>();
int layer = 0;
while(q.size() > 0) {
int l = q.size();
layer ++;
for(int i = 0; i < l; i++) {
String currWord = q.poll();
adjList.put(currWord, new ArrayList<String>());
List<String> next = map.get(currWord);
for(String s: next) {
if(currWord.equals(endWord))
return layer;
if(visited.containsKey(s) && visited.get(s) != layer)
continue;
visited.put(s, layer);
adjList.get(currWord).add(s);
q.add(s);
}
}
}
return 0;
}
}
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
# edge case
if endWord not in wordList:
return 0
# regular case
ch = 'abcdefghijklmnopqrstuvwxyz'
pathCnt = {beginWord: 1}
queue = [beginWord]
while len(queue) != 0:
word = queue.pop(0)
for i in range(len(word)):
newWord = word
for j in range(len(ch)):
newWord = newWord[:i] + ch[j] + newWord[i+1:]
if newWord in wordList and newWord == endWord:
return pathCnt[word]+1
if newWord in wordList and newWord not in pathCnt:
pathCnt[newWord] = pathCnt[word] + 1
queue.append(newWord)
return 0
class Solution:
def ladderLength(self, beginWord: str, endWord: str, wordList: List[str]) -> int:
# edge case
if endWord not in wordList:
return 0
# regular case
ch = 'abcdefghijklmnopqrstuvwxyz'
queue = [beginWord]
res = 0
while len(queue) != 0:
n = len(queue)
while n > 0:
word = queue.pop(0)
if word == endWord:
return res + 1
for i in range(len(word)):
newWord = word
for j in range(len(ch)):
newWord = newWord[:i] + ch[j] + newWord[i+1:]
if newWord in wordList and newWord != word:
wordList.remove(newWord)
queue.append(newWord)
n -= 1
res += 1
return 0
学习贴士:
int, char 等基本数据类型可以直接用==比较大小,== 比较的是值,但String 不能直接比较,String a == String b 比较的是地址,地址当然不可能相等,可以用String1.equals(String 2)比较。