I am trying to solve LC126, and got a memory limit exceeded for the following solution. I've seen the answer here -- so I'll try to use Dijkstra as well, but I would like to understand why I get the memory limit exceeded, and to learn how I could improve my code.
The main idea: BFS on paths, i.e. from start word, build the intermediate paths starting with the start word, then, extend these paths with neighbors, if not visited. Keep only paths of shortest length.
vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
vector<vector<string>> res;
unordered_set<string> wordsList(wordList.begin(), wordList.end());
if (wordsList.count(endWord) == 0) {
return res;
}
unordered_set<string> visited;
queue<vector<string>> q;
q.push(vector<string>({beginWord}));
int min_len = wordList.size() + 1;
unordered_map<string, vector<string>> neigh;
for (const auto& wd: wordsList) {
neigh[wd] = getNeighbors(wd, wordsList);
}
neigh[beginWord] = getNeighbors(beginWord, wordsList);
while (! q.empty()) {
vector<string> crtPath = q.front();
q.pop();
string lastNode = crtPath.back();
visited.insert(lastNode);
for (const string& nn: neigh[lastNode]) {
if (visited.count(nn) != 0) {
continue;
}
vector<string> newPath(crtPath);
newPath.emplace_back(nn);
if (nn == endWord) {
if (newPath.size() == min_len) {
res.push_back(newPath);
}
else if (newPath.size() < min_len) {
res = {newPath};
min_len = newPath.size();
}
}
else {
if (newPath.size() <= min_len) {
q.push(newPath);
}
}
}
}
return res;
}
vector<string> getNeighbors(const string& node, const unordered_set<string>&nodes) {
vector<string> result;
string word = node;
for (int ii = 0; ii < node.length(); ++ii) {
char old_char = word[ii];
for (char ch = 'a'; ch <= 'z'; ++ch) {
if (ch == old_char) {
continue;
}
word[ii] = ch;
if (nodes.count(word) != 0) {
result.emplace_back(word);
}
}
word[ii] = old_char;
}
return result;
}
using
statements. Or perhaps even ausing namespace
, about which reviewers would certainly have something to say! \$\endgroup\$