BiruLyu
5/30/2017 - 11:40 PM

127. Word Ladder.java

/*
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;
    }
}