LeetCode 127. Word Ladder 單詞接龍(C++/Java)

題目:

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:優化

  1. Only one letter can be changed at a time.
  2. Each transformed word must exist in the word list. Note that beginWordis not a transformed word.

Note:ui

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.
  • You may assume no duplicates in the word list.
  • You may assume beginWord and endWord are non-empty and are not the same.

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;
    }
}
相關文章
相關標籤/搜索