1. BFS Storing Full Paths in Queue
Intuition
Store entire paths in the BFS queue: queue<vector<string>>. On each level, collect words used in paths so they are not reused in deeper levels. Terminate when paths reaching endWord are found. While simple, copying vector paths at every step incurs significant memory and time overhead.
Algorithm
- Initialize queue of paths with
[[beginWord]]. - Store dictionary in a set.
- Keep track of words visited on the current level to remove them from dictionary after the level finishes.
- While queue is not empty and no paths reached
endWord: - For each path in queue:
- Mutate last word to find valid next words in dictionary.
- Create new path
[...path, nextWord]and push to next level queue. - Collect all paths ending in
endWord.
#include <iostream>#include <vector>#include <string>#include <unordered_set>#include <queue> std::vector<std::vector<std::string>> findLaddersBFSQueue(std::string beginWord, std::string endWord, std::vector<std::string>& wordList) { std::unordered_set<std::string> dict(wordList.begin(), wordList.end()); if (dict.find(endWord) == dict.end()) return {}; std::queue<std::vector<std::string>> q; q.push({beginWord}); std::vector<std::vector<std::string>> result; std::unordered_set<std::string> visitedThisLevel; bool found = false; while (!q.empty() && !found) { int size = q.size(); visitedThisLevel.clear(); for (int k = 0; k < size; ++k) { auto path = q.front(); q.pop(); std::string word = path.back(); for (int i = 0; i < (int)word.size(); ++i) { char orig = word[i]; for (char c = 'a'; c <= 'z'; ++c) { word[i] = c; if (dict.find(word) != dict.end()) { visitedThisLevel.insert(word); auto newPath = path; newPath.push_back(word); if (word == endWord) { result.push_back(newPath); found = true; } else { q.push(newPath); } } } word[i] = orig; } } for (const auto& w : visitedThisLevel) { dict.erase(w); } } return result;} int main() { std::vector<std::string> words = {"hot","dot","dog","lot","log","cog"}; auto res = findLaddersBFSQueue("hit", "cog", words); std::cout << "Shortest Ladders count: " << res.size() << std::endl; for (auto& path : res) { for (auto& w : path) std::cout << w << " "; std::cout << std::endl; } return 0;}Time & Space Complexity
- Time complexity:
O(N * 26^L * L) with large constants due to path vector copying. - Space complexity:
O(N * L * (number of paths)) which causes high memory usage.