Word Ladder II (LeetCode)

Question:

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

 

根据字典重新建立无方向图。每个节点是一个string,节点连接的点是它变换一个字符后形成的string。则题目要求就变成求这个图上两点之间的最短距离。

可以用DFS或者BFS,既然是求最短距离,不是所有距离,应该BFS会更高效一些。

写了两次,第一次是用string建立的连接表。后来改用int建立,然后用一个vector和map建立string和int之间的关联。所以BFS处理的时候都只需要跟int打交道,能节约一些时间和空间。

class Solution {
public:
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        
        unordered_map<string, int> dictIndex;
        vector<string> dictVector;
        
        int index = 0;
        int startIndex = 0;
        int endIndex = 0;
        
        for (auto it = dict.begin(); it != dict.end(); ++it)
        {
            dictIndex[*it] = index;
            dictVector.push_back(*it);
            
            if (*it == start)
                startIndex = index;
                
            if (*it == end)
                endIndex = index;
                
            index ++;
        }
        
        // build adject table first
        std::unordered_map<int, vector<int>> adjTable;
        
        for (int i = 0; i < index; i++)
        {
            string str = dictVector[i];
            
            for (int j = 0; j < str.size(); j++)
            {
                char ch = str[j];
                for (int k = 0; k < 26; k++)
                {
                     str[j] = 'a'+k;
                        
                      if (str != dictVector[i] && dict.find(str) != dict.end())
                      {
                          adjTable[i].push_back(dictIndex[str]);
                      }
                }
                
                str[j] = ch;
            }
        }
        
        // bfs
        
        std::unordered_set<int> visited;
        std::queue<vector<int>> q;
        
        vector<int> v;
        v.push_back(startIndex);
        visited.insert(startIndex);
        
        q.push(v);
        q.push(vector<int>()); // empty vector string to indicate the end of line
        
        std::unordered_set<int> visitedThisLevel;
        
        vector<vector<string>> result;
        
        while (!q.empty())
        {
            vector<int>& words = q.front();
            
            if (!words.empty())
            {
                int lastword = words[words.size()-1];
                
                for (int i = 0; i < adjTable[lastword].size(); i++)
                {
                    if (visited.find(adjTable[lastword][i]) == visited.end())
                    {
                        if (adjTable[lastword][i] == endIndex)
                        {
                            result.push_back(vector<string>());
                            ConvertVectorIntToString(words, result.back(), dictVector);
                            result.back().push_back(dictVector[adjTable[lastword][i]]);
                        }
                        else
                        {
                            q.push(words);
                            q.back().push_back(adjTable[lastword][i]);
                            visitedThisLevel.insert(adjTable[lastword][i]);
                        }
                    }
                }
            }
            else
            {
                if (!result.empty())
                    break;
                
                // end of this level
                visited.insert(visitedThisLevel.begin(), visitedThisLevel.end());
                visitedThisLevel.clear();
                
                if (q.size() == 1)
                    break;
                
                q.push(words);
            }
            
            q.pop();
        }
        
        return result;
        
    }
    
    void ConvertVectorIntToString(vector<int>& intVector, vector<string>& strVector, vector<string>& list)
    {
        for (int i = 0; i < intVector.size(); i++)
            strVector.push_back(list[intVector[i]]);
    }
};

 

 

class Solution {
public:
    vector<vector<string>> findLadders(string start, string end, unordered_set<string> &dict) {
        // build adject table first
        std::unordered_map<std::string, vector<string>> adjTable;
        
        for (auto it = dict.begin(); it != dict.end(); ++it)
        {
            string str = *it;
            
            for (int i = 0; i < str.size(); i++)
            {
                char ch = str[i];
                for (int j = 0; j < 26; j++)
                {
                     str[i] = 'a'+j;
                        
                      if (str != *it && dict.find(str) != dict.end())
                      {
                          adjTable[*it].push_back(str);
                      }
                }
                
                str[i] = ch;
            }
        }
        
        // bfs
        
        std::unordered_set<string> visited;
        
        std::queue<vector<string>> q;
        
        vector<string> v;
        v.push_back(start);
        visited.insert(start);
        
        q.push(v);
        q.push(vector<string>()); // empty vector string to indicate the end of line
        
        std::unordered_set<string> visitedThisLevel;
        
        vector<vector<string>> result;
        
        while (!q.empty())
        {
            vector<string>& words = q.front();
            
            if (!words.empty())
            {
                string lastword = words[words.size()-1];
                
                for (int i = 0; i < adjTable[lastword].size(); i++)
                {
                    if (visited.find(adjTable[lastword][i]) == visited.end())
                    {
                        if (adjTable[lastword][i] == end)
                        {
                            result.push_back(words);
                            result.back().push_back(adjTable[lastword][i]);
                        }
                        else
                        {
                            q.push(words);
                            q.back().push_back(adjTable[lastword][i]);
                            visitedThisLevel.insert(adjTable[lastword][i]);
                        }
                    }
                }
            }
            else
            {
                if (!result.empty())
                    break;
                
                // end of this level
                visited.insert(visitedThisLevel.begin(), visitedThisLevel.end());
                visitedThisLevel.clear();
                
                if (q.size() == 1)
                    break;
                
                q.push(words);
            }
            
            q.pop();
        }
        
        return result;
        
    }
};

 

posted @ 2015-01-20 14:48  smileheart  阅读(138)  评论(0)    收藏  举报