【leetcode】133. 克隆图

45 阅读1分钟

leetcode-133.png

题目要求我们复制一个无向图,输入是图中某个节点。由于是无向图,且可能存在环,如果不记录已经访问过的节点,会导致无限递归或重复创建节点

核心思路

为避免重复创建或进入死循环,我们可以使用一个 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 避免了递归栈溢出的风险