[leetcode] 126. Word Ladder II 解题报告

59 篇文章 0 订阅
5 篇文章 0 订阅

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

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord toendWord, 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.

思路: 和 Word Ladder相比多了要记录路径, 这样我们为每一个结点记录一下父结点, 这样最后的时候我们就从终点开始一个个往前找其父结点, 直到找到起始点, 然后翻转一下加入结果集合中即可.

大概过程差不多, 但是有点不同的是当我们将字典中的一个字符串删除的时候在另一条路径上可能还会用到这个字符. 也就是像这样:

A -> C -> D,    B->C->D

他们都会经过C, 并且两个都是最短的路径, 在A的时候搜索到C, 并且将C从字典中删除, 当B在搜索与其距离为1的字符串时, C已经不在字典中了, 那么怎么办呢? 我们设置一个hash表用来存储一个字符串的父结点集合, 这样C不在字典中再去查hash表看C是否在hash表中, 如果在的话并且C的父结点层次和B一样, 那么就将B也加入到C的父结点结合中去. 可以知道, 一个字符串的父结点集合的距离起点的距离必然是相等的, 也就是说他们都是最短距离.

最后遍历完所有的点之后, 再用DFS从终点往前找出所有集合即可.

不得不吐槽一句这是哪个变态的公司问的问题, 第二遍写的时候居然还不如第一次写的, 可能我已经昏了, 毕竟已经快凌晨4点了, 本来可以三点睡的, 可恶!

代码如下:

class Solution {
public:
    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>> 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;
    }
    vector<vector<string>> result;
    unordered_map<string, set<pair<string, int>>> hash;
    queue<pair<string, int>> que;
};


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值