class Solution:
# @param start, a string
# @param end, a string
# @param dict, a set of string
# @return an integer
def __init__(self):
self.visited = set()
def ladderLength(self, start, end, dict):
if start == end:
return 1
dict.add(end)
# bfs
queue = collections.deque()
queue.appendleft(start)
step = 1
while queue:
size = len(queue)
step += 1
for i in range(size):
node = queue.pop()
for neighbor in self.getNeighbors(node, dict):
if neighbor == end: return step
queue.appendleft(neighbor)
self.visited.add(neighbor)
return 0
def replace(self, str, index, c):
lst = list(str)
lst[index] = c
return ''.join(lst)
def getNeighbors(self, str, dict):
ret = []
for i in range(len(str)):
for c in range(ord('a'), ord('z') + 1):
neighbor = self.replace(str, i, chr(c))
if neighbor in dict:
if neighbor in self.visited:
continue
ret.append(neighbor)
return ret
public class Solution {
/**
* @param start, a string
* @param end, a string
* @param dict, a set of string
* @return an integer
*/
private Set<String> visited;
public int ladderLength(String start, String end, Set<String> dict) {
if (start.equals(end)) return 1;
dict.add(end); // 先把end加入dict,否则无法直接判断终点
visited = new HashSet<String>();
Deque<String> queue = new LinkedList<>();
queue.addFirst(start);
int step = 1;
while (! queue.isEmpty()) {
int size = queue.size();
step++;
for (int i = 0; i < size; ++i) {
String node = queue.removeLast();
for (String neighbor : getNeighbors(node, dict)) {
// 无需判断是否在visited中,因为getNeighbors已经判断过了
if (neighbor.equals(end)) return step;
queue.addFirst(neighbor);
visited.add(neighbor);
}
}
}
return 0;
}
private String replace(String str, int index, char c) {
char[] arr = str.toCharArray();
arr[index] = c;
return String.valueOf(arr);
}
private List<String> getNeighbors(String node, Set<String> dict) {
List<String> ret = new ArrayList<>();
for (int i = 0; i < node.length(); ++i) {
for (int c = 'a'; c <= 'z'; ++c) {
String str = replace(node, i, (char)c);
if (dict.contains(str)) {
if (! visited.contains(str)) {
ret.add(str);
}
}
}
}
return ret;
}
}
class Solution {
public:
int ladderLength(string &start, string &end, unordered_set<string> &dict) {
if (start == end) return 1;
dict.insert(start);
dict.insert(end);
deque<string> q;
q.push_back(start);
unordered_set<string> visited;
visited.insert(start);
int step = 1;
while (! q.empty()) {
int size = q.size();
for (int i = 0; i < size; ++i) {
string curr = q.front(); q.pop_front();
vector<string> nextWords;
getNextWord(curr, dict, nextWords);
for (string nextWord : nextWords) {
// visit 当前word,检查其是否已经visited,如果不是,将其加入visited set
if (! visited.insert(nextWord).second) continue;
if (nextWord == end) return step + 1;
q.push_back(nextWord);
}
}
++step;
}
return -1;
}
private:
void getNextWord(const string& curr, const unordered_set<string>& dict, vector<string>& res) {
for (int i = 0; i < curr.size(); ++i) {
for (int j = 0; j < 25; ++j) {
string s = curr;
s[i] = 'a' + j;
if (s != curr && dict.count(s)) {
res.push_back(s);
}
}
}
}
};
public class Solution {
private Set<String> visited;
public int ladderLength(String start, String end, List<String> wordList) {
if (start.equals(end)) return 1;
Set<String> dict = new HashSet<>(wordList);
// dict.add(end); // 先把end加入dict,否则无法直接判断终点
// problem changed, now, instead adding end into dict, we need to check if end is in dict first
if (!dict.contains(end)) return 0;
visited = new HashSet<String>();
Deque<String> queue = new LinkedList<>();
queue.addFirst(start);
int step = 1;
while (! queue.isEmpty()) {
int size = queue.size();
step++;
for (int i = 0; i < size; ++i) {
String node = queue.removeLast();
for (String neighbor : getNeighbors(node, dict)) {
// 无需判断是否在visited中,因为getNeighbors已经判断过了
if (neighbor.equals(end)) return step;
queue.addFirst(neighbor);
visited.add(neighbor);
}
}
}
return 0;
}
private String replace(String str, int index, char c) {
char[] arr = str.toCharArray();
arr[index] = c;
return String.valueOf(arr);
}
private List<String> getNeighbors(String node, Set<String> dict) {
List<String> ret = new ArrayList<>();
for (int i = 0; i < node.length(); ++i) {
for (int c = 'a'; c <= 'z'; ++c) {
String str = replace(node, i, (char)c);
if (dict.contains(str)) {
if (! visited.contains(str)) {
ret.add(str);
}
}
}
}
return ret;
}
}
class Solution {
public:
int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
unordered_set<string> wordSet(wordList.begin(), wordList.end());
deque<string> queue{beginWord};
if (!wordSet.count(endWord)) return 0;
int level = 0;
while (!queue.empty()) {
level++;
int size = queue.size();
for (int i = 0; i < size; ++i) {
string word = std::move(queue.back());
if (word == endWord) return level;
queue.pop_back();
auto neighbors = getNeighbors(word, wordSet);
queue.insert(queue.begin(), neighbors.begin(), neighbors.end());
}
}
return 0;
}
private:
vector<string> getNeighbors(string& word, unordered_set<string>& wordSet) {
vector<string> ret;
for (int i = 0; i < word.size(); ++i) {
for (char c = 'a'; c <= 'z'; ++c) {
if (c != word[i]) {
string tmp = word;
tmp[i] = c;
if (wordSet.count(tmp)) {
// std::cout << neighbor << std::endl;
wordSet.erase(tmp); // 在wordSet中去掉,相当于标记为visited
ret.push_back(std::move(tmp));
}
}
}
}
return ret;
}
};