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; } };
浙公网安备 33010602011771号