1. Iterative BFS with Queue and Hash Map
Intuition
Starting from the given root, instantiate its clone and store it in a hash map. Enqueue the original node. While the queue is non-empty, dequeue a node, iterate its neighbors, clone any unvisited neighbors, and append cloned neighbors to the current cloned node.
Algorithm
- If node is null, return null.
- Initialize queue q and push original node.
- Initialize hash map clonedMap: original Node* -> cloned Node*.
- Create clone of root: clonedMap[node] = new Node(node.val).
- While queue is not empty:
- Pop original node curr from q.
- For each neighbor in curr.neighbors:
- If neighbor not in clonedMap:
- clonedMap[neighbor] = new Node(neighbor.val).
- Push neighbor into q.
- clonedMap[curr].neighbors.append(clonedMap[neighbor]).
- Return clonedMap[node].
#include <iostream>#include <vector>#include <unordered_map>#include <queue> class Node {public: int val; std::vector<Node*> neighbors; Node() : val(0) {} Node(int _val) : val(_val) {} Node(int _val, std::vector<Node*> _neighbors) : val(_val), neighbors(_neighbors) {}}; class Solution {public: Node* cloneGraph(Node* node) { if (!node) return nullptr; std::unordered_map<Node*, Node*> cloned; std::queue<Node*> q; cloned[node] = new Node(node->val); q.push(node); while (!q.empty()) { Node* curr = q.front(); q.pop(); for (Node* neighbor : curr->neighbors) { if (cloned.find(neighbor) == cloned.end()) { cloned[neighbor] = new Node(neighbor->val); q.push(neighbor); } cloned[curr]->neighbors.push_back(cloned[neighbor]); } } return cloned[node]; }}; int main() { Node* n1 = new Node(1); Node* n2 = new Node(2); n1->neighbors.push_back(n2); n2->neighbors.push_back(n1); Solution sol; Node* cloned = sol.cloneGraph(n1); std::cout << "Original root: " << n1->val << ", Cloned root: " << cloned->val << "\n"; std::cout << "Cloned neighbor val: " << cloned->neighbors[0]->val << " (Expected: 2)\n"; return 0;}Time & Space Complexity
- Time complexity:
O(V + E) - Space complexity:
O(V)