繁体   English   中英

为什么只有我认为 Leetcode "133. Clone Graph" 的时间复杂度是 O(E) 而不是 O(V+E)

[英]Why only I think the Time Complexity of Leetcode "133. Clone Graph" is O(E) instead of O(V+E)

我有一个关于 leetcode 图问题的问题 [133. 克隆图]“https://leetcode.com/problems/clone-graph/”。

我使用 DFS 来解决这个问题,这是我的 javascript 代码:

/**
 * // Definition for a Node.
 * function Node(val, neighbors) {
 *    this.val = val === undefined ? 0 : val;
 *    this.neighbors = neighbors === undefined ? [] : neighbors;
 * };
 */

/**
 * @param {Node} node
 * @return {Node}
 */
var cloneGraph = function(node) {
    if(!node) return null;
    const visited = new Map();
    
    const dfs = (node) => {
        const n = [];
        if(visited.has(node.val)) return visited.get(node.val);
        let newNode = new Node(node.val);
        visited.set(node.val,newNode);
        
        for(let on of node.neighbors){
            n.push(dfs(on));
        }
        
        newNode.neighbors = n;
        return newNode;
    }
    
    return dfs(node);
};

我的解决方案图是这样的:

在此处输入图像描述

假设 V/E 是图的顶点/边。

我发现有很多人说这个问题的时间复杂度是 O(V+E),但我无法理解,因为我认为在这种情况下它是 O(E)。

在我看来,我们的输入只是一个节点对象而不是一个相邻的列表,它是一个无向图,所以我们不需要检查每个节点的连续序列,我们只需要从输入“节点”跟踪它和然后它会扫描整个图,这只是一种像树一样的正常 DFS 问题。

那里有什么问题吗? 如果是,谁能解释为什么我对这个解决方案有误解?

我发现有很多人说这个问题的时间复杂度是 O(V+E),但我无法理解,因为我认为在这种情况下它是 O(E)。

你是绝对正确的。 代码挑战表明图是连接的,这是一个重要信息。 这意味着至少有 V - 1 条边。 由于该算法是通过在每个方向上仅访问一次边来驱动的,并且节点不会以其他方式访问而不是通过边旅行(除了一次,对于第一个节点),O(E) 与 O(V+ E)。

在每个具有n个顶点的简单图中,边数受n^2限制,因此O(E) = O(V^2) 从完整的图中可以看出,这个界限很紧(每个顶点都相互连接)。

然而,对于许多(自然的或人为的)图类,预先知道的边数是有限制的(例如,树正好有V-1边),因此根据被正式处理的VE来表达复杂性度量是很流行的作为独立实体。

通常,DFS 涉及O(V+E)操作,因为...

  1. 每个顶点都被访问,无论是作为断开连接图的新组件中的初始顶点,还是在 dfs 期间跟随边的过程中。
  2. (接近)每条边都被访问:如果您事先知道它在已经看到的顶点处结束,则只能跳过一条,但要知道您需要沿着边找出...

似乎有一个可能的捷径:看到所有顶点后立即停止 dfs。 但这取决于 dfs 的目的——如果你想建立一个生成树,那没关系,如果你想检测一个循环,那就不行。

回到您的特定设置:必须访问所有顶点和所有边以克隆图,因此O(V+E) 但是,如果图是连接的,则您事先知道在访问了所有边之后您将看到所有顶点,因此: O(E)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM