Word Ladder
Given two words (start and end), and a dictionary, find the length of shortest transformation sequence from start to end, such that:
- Only one letter can be changed at a time
- Each intermediate word must exist in the dictionary
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:
- Return 0 if there is no such transformation sequence.
- All words have the same length.
- All words contain only lowercase alphabetic characters.
LeetCode: https://oj.leetcode.com/problems/word-ladder/
這道題的求解思路爲:對於start,首先找出dict中和start只有一個字符不同的字符串集合S1,對於該S1中的字符串,start到他們的最短距離爲1;然後再求解dict中和S1中字符串只相差一個字符並且沒有出現在S1中的字符集合S2;則start到S2中的字符的最短距離爲2,通過上述過程計算循環計算下去,直到某個集合Si中出現end,則找到start到end的最短距離。
其實敏感的同學可以發現者其實是一顆以start爲根的樹,樹中的節點包括start、end、dict中的字符串(如果包含end,則end一定爲葉節點,但有可能出現在多個位置上);本題的目標其實是要找到從start到end的最短路徑;對於這類問題,一般都採用DFS或BFS,由於樹本身並沒有事先建立好,所以不太適合採用DFS;而通過上面求解思路可知,採用BFS比較恰當。
代碼如下:
public class Solution {
public int ladderLength(String start, String end, Set<String> dict) {
if(start == null || end == null || start.length() == 0 || end.length() == 0 || start.length() != end.length())
return 0;
Queue<String> queue = new LinkedList<String>();
HashSet<String> visited = new HashSet<String>();
queue.offer(start);
int depth = 1;
int cur = 1;
int next = 0;
while(!queue.isEmpty()){
String e = queue.poll();
cur--;
for(int i = 0; i < e.length(); i++){
char[] ca = e.toCharArray();
for(char c = 'a'; c <= 'z'; c++){
ca[i] = c;
String s = new String(ca);
if(s.equals(end))
return depth+1;
if(dict.contains(s) && !visited.contains(s)){
queue.offer(s);
visited.add(s);
next++;
}
}
}
if(cur == 0){
cur = next;
next = 0;
depth++;
}
}
return 0;
}
}