[英]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
边),因此根据被正式处理的V
和E
来表达复杂性度量是很流行的作为独立实体。
通常,DFS 涉及O(V+E)
操作,因为...
似乎有一个可能的捷径:看到所有顶点后立即停止 dfs。 但这取决于 dfs 的目的——如果你想建立一个生成树,那没关系,如果你想检测一个循环,那就不行。
回到您的特定设置:必须访问所有顶点和所有边以克隆图,因此O(V+E)
。 但是,如果图是连接的,则您事先知道在访问了所有边之后您将看到所有顶点,因此: O(E)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.