算法思路(BFS):
該算法是一個廣度搜索問題,查找變換的最優路徑(即變換的次數最少)。在java中,因爲不能直接構建的一個數據對,所以只能創建一個類Pair2,有2個成員word和step,含義:到達當前單詞所經歷的單詞總個數(也可以說是路徑長度)。創建一個以Pair2爲類型的隊列,將當前數據對封裝成Pair2類對象後放入隊列。設置一個String類型HashSet記錄已訪問的單詞。在遍歷中,先出隊,然後匹配該單詞的所有能變換的單詞,返回一個String數組,然後遍歷該數組,如果找到了目標單詞,則返回step+1(因爲還有一次變換就能得到,所以+1),如果set中不包含該單詞(即沒有訪問到),則將該單詞加入set中並且new一個Pair對象(參數word,step+1)後將其放入隊列中。重複上述操作直到隊列爲空。
注意:在匹配該單詞的所有能變換的單詞時,需要在一個給定的單詞表中查找,題目給定的單詞表是list數組,所以查找一個單詞的時間複雜的是O(n),如果按照這中方式查找的話,是會超時的,所以應將時間複雜度降到O(1),解決方法:將單詞表放入哈希集中,可以實現O(1)時間複雜度的查找。
該算法的時間複雜度O(n2),空間複雜度O(n)。參考代碼:
class Pair2{
String word;
int step;
public Pair2(String word,int step){
this.word = word;
this.step = step;
}
}
//leetcode 279. Perfect Squares
public static int ladderLength(String beginWord, String endWord, List<String> wordList) {
HashSet<String> wlSet = new HashSet<String>();
for(int i=0;i<wordList.size();i++){
wlSet.add(wordList.get(i));
}
HashSet<String> set = new HashSet<String>();
Queue<Pair2> queue = new LinkedList<Pair2>();
queue.add(new Pair2(beginWord,1));
while(!queue.isEmpty()){
Pair2 pair = queue.remove();
List<String> list = matchWord(pair.word,wlSet);
if(list!=null){
for(int i=0;i<list.size();i++){
String s = list.get(i);
if(s.equals(endWord))
return pair.step+1;
if(!set.contains(s)){
set.add(s);
queue.add(new Pair2(s,pair.step+1));
}
}
}
}
return 0;
}
public static List<String> matchWord(String word,HashSet<String> wordList){
List<String> list = new ArrayList<String>();
String abc = "qwertyuioplkjhgfdsazxcvbnm";
StringBuilder match = new StringBuilder(word);
for(int i=0;i<match.length();i++){
for(int j=0;j<abc.length();j++){
match.setCharAt(i, abc.charAt(j));
if(!match.toString().equals(word)&&wordList.contains(match.toString()))
list.add(match.toString());
}
match.setCharAt(i, word.charAt(i));
}
return list;
}