[Leetcode] 126. 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.

For example,

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

Return

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

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.

思路

由于需要返回各种可能的路径,所以我们需要为每一个节点记录其父节点,这样我们最后就可以从终点开始一个个往前找其父节点,直到找到起始点,然后翻转一下加入结果集合即可。由于在不同的路径中,可能会包含同一个节点,所以单纯依靠原来的unordered_set是不够的。为此,我们额外定义一个unordered_map,记录一个节点的所有父节点所构成的集合。

有了上述的unordered_map这样的数据结构,我们的思路就是:首先采用广度优先搜索策略建立起来各个节点之间的邻接关系(也就是通过修改一个字母可以变成另一个字母的情况);然后通过深度优先策略找出所有符合条件的路径。

不得不说,这道题目还是比较变态的。

代码

class Solution {  
public: 
    vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) {  
        wordList.insert(endWord);  
        wordList.erase(beginWord);  
        que.push(make_pair(beginWord, 1));  
        while(!que.empty()) {
            auto val = que.front();  
            que.pop();  
            for(int i = 0; i < val.first.size(); i++) {  
                string tem = val.first;  
                for(int j =0; j < 26; j ++) {  
                    tem[i] = 'a' + j;  
                    if(wordList.count(tem)) {  
                        que.push(make_pair(tem, val.second+1));  
                        wordList.erase(tem);  
                        hash[tem].insert(val);  
                    }  
                    else if(hash.count(tem)&&hash[tem].begin()->second==val.second) {
                        hash[tem].insert(val); 
                    }
                }  
            }  
        }  
        DFS(hash[endWord], vector<string>{endWord});  
        return result;  
    }
private:
    void DFS(set<pair<string, int>> st, vector<string> vec) {  
        for(auto val: st) {  
            vec.push_back(val.first);  
            if(hash.count(val.first)==0) {  
                reverse(vec.begin(), vec.end());  
                return result.push_back(vec);  
            }  
            DFS(hash[val.first], vec);  
            vec.pop_back();  
        }  
    }
    vector<vector<string>> result;  
    unordered_map<string, set<pair<string, int>>> hash;  
    queue<pair<string, int>> que;  
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值