题目要求我们复制一个无向图,输入是图中某个节点。由于是无向图,且可能存在环,如果不记录已经访问过的节点,会导致无限递归或重复创建节点。
核心思路
为避免重复创建或进入死循环,我们可以使用一个 Map(或 HashMap)记录原节点和克隆节点的映射关系。这样每当遇到一个已访问过的节点时,可以直接复用它对应的克隆节点。
DFS
var cloneGraph = function (node) {
if (!node) return null;
let hash = new Map();
var dfs = function (current) {
// 查询是否之前遇到过该节点
if (hash.has(current)) return hash.get(current);
// 创建复制节点
let newNode = new _Node(current.val);
// 记录该节点
hash.set(current, newNode)
for (let n of current.neighbors) {
// 轮询邻接节点
newNode.neighbors.push(dfs(n));
}
return newNode;
};
return dfs(node);
};
特点:
- 利用递归进行深度优先遍历
- 每访问一个新节点,就创建一个对应的克隆节点并记录
- 当再次遇到已访问节点时,直接返回克隆结果,避免死循环
BFS
var cloneGraph = function (node) {
if (!node) return null;
let queue = [node]
let hash = new Map()
hash.set(node, new _Node(node.val))
while(queue.length){
let current = queue.shift()
for(let n of current.neighbors){
if(!hash.has(n)){
hash.set(n, new _Node(n.val))
queue.push(n)
}
// 旧图里面的节点放倒clone节点里面
hash.get(current).neighbors.push(hash.get(n))
}
}
return hash.get(node)
};
特点:
- 通过队列实现图的层级遍历
- 同样利用哈希表记录已克隆的节点,避免重复创建
- 对于更大或更深的图,BFS 避免了递归栈溢出的风险