leetcode 126 Word Ladder II

leetcode 126 Word Ladder II

原题链接:https://leetcode.com/problems/word-ladder-ii/

Description

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 intermediate word must exist in the word list

For example,

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

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

Note:

  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

Solution

跟127那道题差不多,只不过多了要保存路径(所有解)。
一开始用dfs结果超时,一看要求最短路径马上就想到了bfs。
于是胡乱一敲提交上去tle QAQ。
bfs太慢好吧那么来个双向的吧,不幸的是经过一些奇怪的姿势,只能水到31组数据
然后一直wa(总是少了几组解),越写越烦懒得改了。网上搜题解才搞明白了。
具体做法是: 分层bfs,每遍历完一层再扩展下一层。在扩展过程中记得用map
保存新节点和旧节点的父子关系,同时在dic中删除已出现的word防止重复。
最后利用得到的这个map从end出发找start。好了终于过了 卒...
talk is cheap show me the code

127 Word Ladder 戳这里

class Solution {
    using ves = vector<string>;
    using vees = vector<ves>;
    using Hash = map<string, vector<string>>;
public:
    vees findLadders(string start, string end, unordered_set<string> &dic) {
        if(!bfs(start, end, dic)) return ans;
        ves rec;
        dfs(start, end, rec);
        return ans;
    }
private:
    void dfs(string &start, string &end, ves &rec) {
        rec.push_back(end);
        if(start == end) {
            ves temp(rec);
            reverse(temp.begin(), temp.end());
            ans.push_back(temp);
            rec.pop_back();
            return;
        }
        for(auto &r: hsh[end]) {
            dfs(start, r, rec);
        }
        rec.pop_back();
    }
    bool bfs(string start, string end, unordered_set<string> &dic) {
        int cur = 0;
        unordered_set<string> Q[2];
        Q[cur].insert(start);
        auto expandState = [&](unordered_set<string> &from, unordered_set<string> &to) {
            to.clear();
            for(auto &r: from) {
                for(int i = 0; i < (int)r.size(); i++) {
                    string temp = r;
                    for(char j = 'a'; j <= 'z'; j++) {
                        char ch = temp[i];
                        if(ch == j) continue;
                        temp[i] = j;
                        if(dic.find(temp) != dic.end()) {
                            to.insert(temp);
                            hsh[temp].push_back(r);
                        }
                        temp[i] = ch;
                    }
                }
            }
        };
        while(!Q[cur].empty()) {
            for(auto &r: Q[cur]) dic.erase(r);
            expandState(Q[cur], Q[cur ^ 1]);
            cur ^= 1;
            if(Q[cur].find(end) != Q[cur].end()) return true;
        }
        return false;
    }
private:
    Hash hsh;
    vees ans;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值