[leetcode] 126.Word Ladder II

题目:
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from start to end, such that:

Only one letter can be changed at a time
Each intermediate word must exist in the dictionary
For example,

Given:
start = “hit”
end = “cog”
dict = [“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.
题意:
与127题不同的是这道题需要记录所有最短变换的过程。
思路:
依旧需要使用广度优先遍历,不过需要保存元素变化的过程,就是比如从字符串a变化到字符串b,那么就要保存这个变化路径。考虑到这样的变化过程,a->b->c,a->d->c,那么c可以从两个元素b,d变化过来,所以需要记录c的上一个元素有b和d。
使用vector

class Solution {
public:
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        dict.erase(start);
        vector<vector<string>> result;
        if(start == "" || start.size() != end.size())return result;

        queue<string> words;
        words.push(start);
        words.push("");

        vector<vector<int>> index;
        vector<int> ind(1,-1);
        index.push_back(ind);

        unordered_map<string,int> first;
        unordered_map<string,int> second;

        vector<string> word_s(1,start);

        int i = 0;
        int len = start.size();

        bool found = false;
        vector<int> res_index;

        while(true) {
            string word = words.front();
            words.pop();
            if(words.empty())break;
            if(word == "") {
                first.clear();
                if(found)break;
                words.push("");
                i--;
            }
            for(auto m = 0; m < len; m++)
                for(auto n = 'a'; n <= 'z'; n++) {
                    char letter = word[m];
                    word[m] = n;
                    if(word == end) {
                        found = true;
                        word[m] = letter;
                        res_index.push_back(i);
                        continue;
                    }
                    if(dict.find(word) == dict.end() && first.find(word) == first.end()) {
                        word[m] = letter;
                        continue;
                    }
                    else if(first.find(word) != first.end()) {
                        index[first[word]].push_back(i);
                        word[m] = letter;
                        continue;
                    }
                    words.push(word);

                    first[word] = index.size();

                    index.push_back(vector<int>(1,i));

                    word_s.push_back(word);

                    dict.erase(word);

                    word[m] = letter;
                }
            i++;
        }

        for(auto iter = res_index.begin(); iter != res_index.end(); iter++) {
            list<string> tmp;
            tmp.push_front(word_s[*iter]);
            getAllResult(index, *iter, word_s, end, tmp, result);
        }
        return result;
    }
    void getAllResult(vector<vector<int>> &index, int i, vector<string> words, string end, list<string>& res,vector<vector<string>>& result){
        for(auto m = 0; m < index[i].size(); m++) {
            if(index[i][m] == -1){
                vector<string> res_t;
                for(auto each:res) {
                    res_t.push_back(each);

                }
                res_t.push_back(end);
                result.push_back(res_t);
                return;
            }
            else {
                cout<<"in else push "<<words[index[i][m]]<<endl;
                res.push_front(words[index[i][m]]);
                getAllResult(index, index[i][m], words, end, res, result);
                //displayVector<string>(result);
                res.pop_front();
               // displayVector<string>(result);
            }
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值