题目:
Given two words (beginWord and endWord), and a dictionary, find the length of shortest transformation sequence from beginWord to endWord, such that:
For example,
Given:
start = "hit"
end = "cog"
dict = ["hot","dot","dog","lot","log"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog"
,
return its length 5
.
Note:
用BFS + 单Queue + 每次与wordDict比较,C++可以刚刚通过时间测试,java不能通过时间测试。于是网上学来BFS + 双Queue + 每次修改一个字符并与wordDict比较,每次止血比较 stringLength * 26次。
C++版:
class Solution { public: int ladderLength(string beginWord, string endWord, unordered_set<string>& wordDict) { if(beginWord == endWord) return 2; if(wordDict.empty()) return 0; wordDict.insert(endWord); queue<pair<string, int>> forward; forward.push(pair<string, int>(beginWord, 1)); if(wordDict.find(beginWord) != wordDict.end()) wordDict.erase(beginWord); while(!forward.empty()) { pair<string, int> front = forward.front(); forward.pop(); if(front.first == endWord) return front.second; for(unordered_set<string>::iterator iter = wordDict.begin(); iter != wordDict.end(); ) { if(distance(*iter, front.first)) { forward.push(pair<string, int>(*iter, front.second+1)); wordDict.erase(iter++); } else { iter++; } } cout << endl; } return 0; } bool distance(const string& a, const string& b) { int diff = 0; for(unsigned int i = 0; i < a.length(); i++) { if(a[i] != b[i]) diff++; if(diff > 1) return false; } if(diff == 1) return true; else return false; } };
注意String比较的时候要用.equals()
public class Solution { public int ladderLength(String beginWord, String endWord, Set<String> wordDict) { if(beginWord == null || endWord == null || wordDict.size() == 0) return 0; Queue<String> queue1 = new LinkedList<>(); Queue<String> queue2 = new LinkedList<>(); queue1.add(beginWord); int distance = 1; while(wordDict.size() != 0 && queue1.size() != 0) { while(queue1.size() != 0) { String current = queue1.poll(); for(int i = 0; i < current.length(); i++) { for(char j = 'a'; j <= 'z'; j++) { String temp = current; if(current.charAt(i) == j) continue; StringBuilder newString = new StringBuilder(current); newString.setCharAt(i, j); current = newString.toString(); if(current.equals(endWord)) return distance + 1; if(wordDict.contains(current)) { queue2.add(current); wordDict.remove(current); } current = temp; } } } distance += 1; queue1.addAll(queue2); queue2.clear(); } return 0; } }
注意复制deque的时候要用深copy。import copy
a = copy.copy(b)
from collections import deque class Solution: # @param beginWord, a string # @param endWord, a string # @param wordDict, a set<string> # @return an integer def ladderLength(self, beginWord, endWord, wordDict): if beginWord == None or endWord == None or len(wordDict) == 0: return 0 q1 = deque() q1.append(beginWord) q2 = deque() distance = 1 while len(wordDict) != 0 and len(q1) != 0: while len(q1) != 0: current = q1.pop() for i in range(len(current)): temp = current for j in "abcdefghijklmnopqrstuvwxyz": if j == i: continue current = current[0:i] + j + current[i+1:] if current == endWord: return distance + 1 if current in wordDict: q2.append(current) wordDict.remove(current) current = temp distance += 1 q1 = copy.copy(q2) q2.clear() return 0