LeetCode|Word Ladder*

Word Ladder

Word Ladder
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:

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.

Note:

  • 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:

    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:

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.

解答:BFS搜索

class Solution {
public:
    int ladderLength(string beginWord, string endWord, vector<string>& wordList) {
        if(wordList.empty()) return 0;
        unordered_set<string> us(wordList.begin(), wordList.end());
        if(us.find(endWord) == us.end()) return 0;
        queue<pair<string, int> > q;
        q.push(make_pair(beginWord, 1));
        us.erase(beginWord);
        string word;
        while(!q.empty()){
            auto p  = q.front();
            q.pop();
            for(int i = 0; i < p.first.size(); ++i){
                for(char c = 'a'; c <= 'z'; ++c){
                    word = p.first;
                    if(word[i] == c) continue;
                    word[i] = c;
                    if(word == endWord) return p.second+1;
                    if(us.find(word) != us.end()){
                        us.erase(word);
                        q.push(make_pair(word, p.second+1));
                    }
                }
            }
        } return 0;
    }
};

Word Ladder II

Word Ladder II
Given two words (beginWord and endWord), and a dictionary’s word list, find all shortest transformation sequence(s) 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 beginWord is not a transformed word.

Note:

  • Return an empty list 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:

Input:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

Output:
[
  ["hit","hot","dot","dog","cog"],
  ["hit","hot","lot","log","cog"]
]

Example 2:

Input:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Output: []

Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.

下面这个代码TLE… 建立edge的过程慢?,深搜也慢,

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <set>
#include <cassert>
using namespace std;

class Solution {
public:
    vector<vector<string> > findLadders(string beginWord, string endWord, vector<string> wordList) {
        res = vector<vector<string> >();
        if(wordList.empty()) return res;
        um = unordered_map<string, bool>();
        for(auto word: wordList) um[word] = false;
        if(um.find(endWord) == um.end()) return res;
        if(um.find(beginWord) == um.end())   // beginWord可能不在词表中
            wordList.push_back(beginWord);
        string word;
        edge = unordered_map<string, vector<string> >();
        for(int i = 0; i < wordList.size(); ++i){
            edge[wordList[i]] = vector<string>();
            int len = wordList[i].size();
            for(int j = 0; j < len; ++j){
                word = wordList[i];
                for(char c = 'a'; c <= 'z'; ++c){
                    word[j] = c;
                    if(wordList[i] != word && um.find(word) != um.end()){
                        edge[wordList[i]].push_back(word);
                    }
                }
            }
        } cur = vector<string>({beginWord});  // initialize list,  等价于 vector<string>(1, beginWord);
        um[beginWord] = true;  // 永远不会再访问beginWord
        cnt = INT_MAX;
        helper(beginWord, endWord);
        return res;
    }
private:
    vector<vector<string> > res;
    unordered_map<string, vector<string> > edge;
    vector<string> cur;
    unordered_map<string, bool> um;
    int cnt;
    inline void helper(string word, string& endWord){
        if(word == endWord){
            if(cur.size() > cnt) return;
            else if(cur.size() == cnt) res.push_back(cur);
            else{
                cnt = cur.size();
                res.clear();
                res.push_back(cur);
            } return;
        } if(cur.size() > cnt) return;  // 剪枝
        for(auto w: edge[word]){
            if(!um[w]){
                um[w] = true;
                cur.push_back(w);
                helper(w, endWord);
                um[w] = false;
                cur.pop_back();
            }
        }
    }
};

int main(){
    //string beginWord = "red", endWord = "tax", arr[] = {"ted","tex","red","tax","tad","den","rex","pee"}; int n = 8;
    // string beginWord = "hit", endWord = "cog", arr[] = {"hot","dot","dog","lot","log","cog"}; int n = 6;
    string beginWord = "qa", endWord = "sq", arr[] = {"si","go","se","cm","so","ph","mt","db","mb","sb","kr","ln","tm","le","av","sm","ar","ci","ca","br","ti","ba","to","ra","fa","yo","ow","sn","ya","cr","po","fe","ho","ma","re","or","rn","au","ur","rh","sr","tc","lt","lo","as","fr","nb","yb","if","pb","ge","th","pm","rb","sh","co","ga","li","ha","hz","no","bi","di","hi","qa","pi","os","uh","wm","an","me","mo","na","la","st","er","sc","ne","mn","mi","am","ex","pt","io","be","fm","ta","tb","ni","mr","pa","he","lr","sq","ye"};int n = 95;
    Solution().findLadders(beginWord, endWord, vector<string>(arr, arr+n));
    return 0;
}

这道题题意简单,看似能做,但是考察的比较全面了。

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <set>
#include <cassert>
using namespace std;

class Solution {
public:
    vector<vector<string> > findLadders(string beginWord, string endWord, vector<string>& wordList) {
        res = vector<vector<string> >();
        if(wordList.empty()) return res;
        visited = unordered_map<string, bool>();
        for(auto word: wordList) visited[word] = false;
        if(visited.find(endWord) == visited.end()) return res;
        if(visited.find(beginWord) == visited.end()){   // beginWord可能不在词表中
            visited[beginWord] = false;
            wordList.push_back(beginWord);
        }
        dis = unordered_map<string, int>();
        edge = unordered_map<string, vector<string> >();

        string word;
        queue<string> q;
        q.push(endWord);
        dis[endWord] = 0;
        visited[endWord] = true;
        while(!q.empty()){  // BFS:计算从endWord到beginWord的距离dis
            string p = q.front();
            // if(p == beginWord) break;
            q.pop();
            for(int j = 0; j < p.size(); ++j){
                word = p;
                for(char c = 'a'; c <= 'z'; ++c){
                    if(c == p[j]) continue;
                    word[j] = c;
                    if(visited.find(word) != visited.end() && !visited[word]){
                        visited[word] = true;
                        dis[word] = dis[p]+1;
                        q.push(word);
                    }
                }
            }
        }
        /* 建立edge */
        for(int i = 0; i < wordList.size(); ++i){
            edge[wordList[i]] = vector<string>();
            int len = wordList[i].size();
            for(int j = 0; j < len; ++j){
                word = wordList[i];
                for(char c = 'a'; c <= 'z'; ++c){
                    word[j] = c;
                    if(wordList[i][j] != c && visited.find(word) != visited.end()){
                        edge[wordList[i]].push_back(word);
                    }
                }
            }
        }

        cur = vector<string>({beginWord});  // initialize list,  等价于 vector<string>(1, beginWord);
        for(auto it = visited.begin(); it != visited.end(); ++it) it->second = false;
        visited[beginWord] = true;  // 永远不会再访问beginWord
        bestDis = dis[beginWord];
        helper(beginWord, endWord);
        return res;
    }
private:
    vector<vector<string> > res;
    unordered_map<string, vector<string> > edge;
    vector<string> cur;
    unordered_map<string, bool> visited;
    unordered_map<string, int> dis;
    int bestDis;
    inline void helper(string word, string& endWord){
        if(word == endWord){
            res.push_back(cur);
            return;
        }
        for(auto w: edge[word]){
            if(!visited[w] && (cur.size()+dis[w] == bestDis)){
                visited[w] = true;
                cur.push_back(w);
                helper(w, endWord);
                visited[w] = false;
                cur.pop_back();
            }
        }
    }
};
void printv(vector< vector<string> >& res){
    for(auto v: res){
        for(auto w:v) cout << w << ' ';
        cout << endl;
    } return;
}
int main(){
     //string beginWord = "red", endWord = "tax", arr[] = {"ted","tex","red","tax","tad","den","rex","pee"}; int n = 8;
    //string beginWord = "hit", endWord = "cog", arr[] = {"hot","dot","dog","lot","log","cog"}; int n = 6;
     string beginWord = "qa", endWord = "sq", arr[] = {"si","go","se","cm","so","ph","mt","db","mb","sb","kr","ln","tm","le","av","sm","ar","ci","ca","br","ti","ba","to","ra","fa","yo","ow","sn","ya","cr","po","fe","ho","ma","re","or","rn","au","ur","rh","sr","tc","lt","lo","as","fr","nb","yb","if","pb","ge","th","pm","rb","sh","co","ga","li","ha","hz","no","bi","di","hi","qa","pi","os","uh","wm","an","me","mo","na","la","st","er","sc","ne","mn","mi","am","ex","pt","io","be","fm","ta","tb","ni","mr","pa","he","lr","sq","ye"};int n = 95;
    vector<string> wordList = vector<string>(arr, arr+n);
    auto res = Solution().findLadders(beginWord, endWord, wordList);
    printv(res);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值