首页 > 其他 > 详细

[宽度优先搜索] leetcode 126 Word Ladder II

时间:2019-08-05 23:54:33      阅读:157      评论:0      收藏:0      [点我收藏+]

problem:https://leetcode.com/problems/word-ladder-ii/

         这道题做的好艰难,感觉还是经验不足导致的。

         一个比较麻烦的地方是,我们需要使用一个path容器来记录访问过的路径,对于每个字符串而言,它可以由多个字符串转换而来,所以路径的上一个位置需要记录成一个set。

        之前使用visit来做每个字符串的访问限制时,发现会漏掉不少情况。比如,在搜索到每i - 1层时,第i - 1层的字符串a和b都可以转换到第i层的字符串c,但由于a先访问到c,给c加了一个visit标记,b就无法访问到c了。这里我卡了很久,最后想到的办法是再维护一个layer容器,记录每个字符串所在的层数,只允许从第i - 1层转换到第i层,否则就会出现死循环(从i-1到i,又从i回到i - 1) 或者出现更长的路径(比如,理想结果是a->c,但如果不加限制地记录path,就会把a -> b -> c也加入到结果中)。因此,在维护path数据结构时,需要限制layer[curWord] + 1 == layer[nextWord]

         对于已经维护完成的path数据结构,还需要把里面的路径提取出来,因为路径存在多条,这里可以使用深搜把所有路径记录下来。

class Solution {
public:
    bool CanTransform(const string& s1, const string& s2)
    {
        int count = 0;
        for(int i = 0;i < s1.size();i++)
        {
            if(s1[i] != s2[i])
            {
                count++;
            }
            if(count > 1) return false;
        }
        return count == 1;
    }
    
    unordered_map<string, unordered_set<string>> path;
    vector<vector<string>> res;
    vector<string> ans;
    void dfs(const string& word)
    {
        ans.push_back(word);
        if(path.find(word) == path.end())
        {
            if(ans.size() >= 2)
            {
                res.push_back(ans);
            }
        }
        else
        {
            for(auto& next : path[word])
            {
                dfs(next);
            }
        }
        ans.pop_back();         
    }
    
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {      
        unordered_map<string, unordered_set<string>> graph;
        wordList.push_back(beginWord);
        bool bFind = false;
        for(int i = 0;i < wordList.size(); i++)
        {
            for(int j = i + 1;j < wordList.size(); j++)
            {
                if(CanTransform(wordList[i], wordList[j]))
                {
                    graph[wordList[i]].insert(wordList[j]);
                    graph[wordList[j]].insert(wordList[i]);
                }
            }
            if(wordList[i] == endWord) bFind = true;
        }
        
        if(!bFind) return res;
        
        unordered_set<string> visit;
        unordered_map<string, int> layer;
        
        queue<string> q;
        
        q.push(beginWord);
        visit.insert(beginWord);
        bool flag = false;
        
        int count = 0;
        while(!q.empty())
        {
            int size = q.size();
            while(size--)
            {
                string cur = q.front();
                q.pop();
                for(auto& word : graph[cur])
                {
                    if(word == endWord)
                    {
                        path[word].insert(cur);
                        flag = true;
                    }
                    if(visit.find(word) == visit.end())
                    {
                        visit.insert(word);
                        q.push(word);
                        layer[word] = count;
                        path[word].insert(cur);
                    }
                    else if(layer[word] == layer[cur] + 1)
                    {
                        path[word].insert(cur);
                    }
                }
            }
            count++;
            if(flag) break;
        }
        dfs(endWord);
        for(int i = 0; i < res.size();i++)
        {
            reverse(res[i].begin(), res[i].end());
        }
        return res;
    }
};

 

[宽度优先搜索] leetcode 126 Word Ladder II

原文:https://www.cnblogs.com/fish1996/p/11306215.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!