Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:優化
Note:ui
Example 1:spa
Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.
Example 2:code
Input: beginWord = "hit" endWord = "cog" wordList = ["hot","dot","dog","lot","log"] Output: 0 Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
給定起始和終止兩個單詞,和一個單詞列表,要求咱們使用列表中的單詞將起始和終止單詞鏈接起來,鏈接的規則是要求每次只改變一個字符,且在列表中存在,終止單詞也須要在列表中。orm
咱們能夠利用廣度優先搜索,從起始單詞開始,將每一位字符從a到z依次改變,若是改變後的單詞在列表中,就記錄下來,並在集合中刪去,這樣作的目的是爲了防止重複的搜索,例如dog-dop-dog,這樣是浪費時間的,當新加入的單詞和最終單詞相同時,返回步驟數便可,若是保存搜索單詞的集合(隊列)爲空時,證實已經搜索結束,且沒有找到,返回0便可。blog
還能夠利用雙向廣度優先搜索進行優化,思想就是同時從起始單詞和終止單詞開始搜索,也是經過改變字符,且在單詞列表中便加入到兩個搜索集中,當一側搜索出來的單詞,在另外一側的搜索單詞集中,意味着出現瞭解。至於搜索的次序,若是當一方的集合中的單詞數量小於另外一方時,就優先從數量小的集合開始搜索。隊列
C++rem
class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { //set<string> dict; unordered_set<string> dict; for(string s:wordList) dict.insert(s); if(dict.count(endWord) == 0) return 0; queue<string> q; q.push(beginWord); int l = beginWord.length(); int step = 0; while(!q.empty()){ step++; int len = q.size(); for(int i = 0; i < len; ++i){ string word = q.front(); q.pop(); for(int j = 0; j < l; ++j){ char ch = word[j]; for(int k = 'a'; k <= 'z'; ++k){ if(k == ch) continue; word[j] = k; if(word == endWord) return step+1; if(dict.count(word) == 0) continue; q.push(word); dict.erase(word); } word[j] = ch; } } } return 0; } };
//Bidirectional BFS //Runtime: 28 ms, faster than 98.16% of C++ online submissions for Word Ladder. class Solution { public: int ladderLength(string beginWord, string endWord, vector<string>& wordList) { //set<string> dict; unordered_set<string> dict; for(string s:wordList) dict.insert(s); if(dict.count(endWord) == 0) return 0; unordered_set<string> q1; unordered_set<string> q2; q1.insert(beginWord); q2.insert(endWord); int l = beginWord.length(); int step = 0; while(!q1.empty() && !q2.empty()){ step++; if(q1.size() > q2.size()) swap(q1, q2); unordered_set<string> q; for(string word:q1){ for(int j = 0; j < l; ++j){ char ch = word[j]; for(int k = 'a'; k <= 'z'; ++k){ if(k == ch) continue; word[j] = k; if(q2.count(word)) return step+1; if(dict.count(word) == 0) continue; q.insert(word); dict.erase(word); } word[j] = ch; } } swap(q, q1); } return 0; } };
Javastring
class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { Set<String> dict = new HashSet<>(wordList); if(!dict.contains(endWord)) return 0; Queue<String> q = new ArrayDeque<>(); q.offer(beginWord); int l = beginWord.length(); int step = 0; while(!q.isEmpty()){ step++; int len = q.size(); for(int i = 0; i < len; ++i){ //String word = q.poll(); StringBuilder word = new StringBuilder(q.poll()); for(int j = 0; j < l; ++j){ char ch = word.charAt(j); for(int k = 'a'; k < 'z'; ++k){ if(ch == k) continue; word.setCharAt(j, (char)k); String w = word.toString(); if(w.equals(endWord)) return step+1; if(!dict.contains(w)) continue; q.offer(w); dict.remove(w); } word.setCharAt(j, ch); } } } return 0; } }
class Solution { public int ladderLength(String beginWord, String endWord, List<String> wordList) { Set<String> dict = new HashSet<>(wordList); if(!dict.contains(endWord)) return 0; Set<String> q1 = new HashSet<>(); q1.add(beginWord); Set<String> q2 = new HashSet<>(); q2.add(endWord); int l = beginWord.length(); int step = 0; while(!q1.isEmpty() && !q2.isEmpty()){ step++; if(q1.size() > q2.size()){ Set<String> temp = q1; q1 = q2; q2 = temp; } Set<String> q = new HashSet<>(); for(String s:q1){ StringBuilder str = new StringBuilder(s); for(int i = 0; i < l; ++i){ char ch = str.charAt(i); for(int j = 'a'; j <= 'z'; ++j){ if(ch == j) continue; str.setCharAt(i, (char)j); String word = str.toString(); if (q2.contains(word)) return step + 1; if(!dict.contains(word)) continue; dict.remove(word); q.add(word); } str.setCharAt(i, ch); } } q1.clear(); q1.addAll(q); } return 0; } }