/*
beginWord to endWord, such that:
Only one letter can be changed at a time.
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,
Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.
*/
/*BFS*/
public class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
HashSet<String> frontier = new HashSet<String>();
HashSet<String> explored = new HashSet<String>();
HashSet<String> wordListHash = new HashSet<String>();
wordListHash.addAll(wordList);
int res = 2;
frontier.add(beginWord);
explored.add(beginWord);
while(!frontier.isEmpty()){
HashSet<String> temp = new HashSet<String>();
for(String word: frontier){
char[] wordchars = word.toCharArray();
for(int i = 0; i < wordchars.length; i++){
for(char c = 'a'; c <= 'z'; c++){
char backup = wordchars[i];
if(wordchars[i] != c){
wordchars[i] = c;
String nextword = new String(wordchars);
if(wordListHash.contains(nextword)){
if(nextword.equals(endWord)) return res;
if(!explored.contains(nextword)){
temp.add(nextword);
explored.add(nextword);
}
}
}
wordchars[i] = backup;
}
}
}//for(String word: frontier)
res ++;
frontier = temp;
}//while
return 0;
}
}
/*Using wordListHash.remove replace the explored judge, a little bit faster*/
public class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
HashSet<String> frontier = new HashSet<String>();
//HashSet<String> explored = new HashSet<String>();
HashSet<String> wordListHash = new HashSet<String>();
wordListHash.addAll(wordList);
int res = 2;
frontier.add(beginWord);
//explored.add(beginWord);
while(!frontier.isEmpty()){
HashSet<String> temp = new HashSet<String>();
for(String word: frontier){
char[] wordchars = word.toCharArray();
for(int i = 0; i < wordchars.length; i++){
for(char c = 'a'; c <= 'z'; c++){
char backup = wordchars[i];
if(wordchars[i] != c){
wordchars[i] = c;
String nextword = new String(wordchars);
if(wordListHash.contains(nextword)){
if(nextword.equals(endWord)) return res;
//if(!explored.contains(nextword)){
temp.add(nextword);
//explored.add(nextword);
wordListHash.remove(nextword);
//}
}
}
wordchars[i] = backup;
}
}
}//for(String word: frontier)
res ++;
frontier = temp;
}//while
return 0;
}
}
/*Two-end BFS*/
/*TESTCASES:
Input :
"hit"
"cog"
["hot","dot","dog","lot","log"]
Output:
0
*/
public class Solution {
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
HashSet<String> frontier = new HashSet<String>();
HashSet<String> frontierEnd = new HashSet<String>();
HashSet<String> wordListHash = new HashSet<String>();
wordListHash.addAll(wordList);
int res = 2;
frontier.add(beginWord);
frontierEnd.add(endWord);
if(!wordListHash.contains(endWord)) return 0;
else
wordListHash.remove(endWord);
while(!frontier.isEmpty() && !frontierEnd.isEmpty()){
HashSet<String> temp = new HashSet<String>();
for(String word: frontier){
char[] wordchars = word.toCharArray();
for(int i = 0; i < wordchars.length; i++){
for(char c = 'a'; c <= 'z'; c++){
char backup = wordchars[i];
if(wordchars[i] != c){
wordchars[i] = c;
String nextword = new String(wordchars);
if(frontierEnd.contains(nextword)) return res;
if(wordListHash.contains(nextword)){
//if(!explored.contains(nextword)){
temp.add(nextword);
//explored.add(nextword);
wordListHash.remove(nextword);
//}
}
}
wordchars[i] = backup;
}
}
}//for(String word: frontier)
res ++;
if(temp.size() < frontierEnd.size()){
frontier = temp;
frontierEnd = frontierEnd;
}
else{
frontier = frontierEnd;
frontierEnd = temp;
}
}//while
return 0;
}
}