You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在O(m+k)时间复杂度下获取图的边集?现有代码为O(m²)

如何在O(m+k)时间复杂度下获取无向图的边集?

你的问题核心是避免无向图边的重复记录,同时把时间复杂度从O(m²)降到O(m+k)。先分析下你原来的代码:

你用frozenset来自动去重,虽然结果正确,但每条无向边会被处理两次(比如顶点0→1和1→0都会被遍历到),而且如果遇到完全图这种极端情况,每个顶点的邻接表包含所有其他顶点,那你的代码会执行O(m²)次操作,这显然不符合你的时间复杂度要求。

优化方案:只记录单向边

无向图的边(u, v)等价于(v, u),所以我们可以只记录u < v的边,这样每条边只会被处理一次,完全不需要去重操作,时间复杂度直接降到O(m+k)——其中m是遍历所有顶点的开销,k是处理所有边的开销(每条边仅处理一次)。

优化后的代码如下:

def edgeset(G):
    edges = set()
    for i in range(len(G)):
        for neighbor in G[i]:
            # 只保留i < neighbor的边,避免重复记录
            if neighbor > i:
                edges.add((i, neighbor))
    return edges

为什么这个是O(m+k)?

  • 外层循环遍历m个顶点,开销是O(m);
  • 内层循环遍历每个顶点的邻接表,但只处理neighbor > i的节点,每条无向边只会被处理一次,总共有k条边,所以这部分开销是O(k);
  • 整体加起来就是O(m + k),完美符合你的需求。

测试验证

用你提供的define_G()生成的图来测试,这个函数返回的图边集应该是:
{(0,1), (0,2), (1,2), (1,3), (1,4), (2,4), (3,4)}
调用优化后的edgeset(define_G())就能得到这个结果,没有重复,效率也更高。

如果你偏好保留frozenset的形式,只需要把(i, neighbor)改成frozenset({i, neighbor})就行,但元组的创建和哈希效率比frozenset更高,更推荐使用元组。

内容的提问来源于stack exchange,提问作者hardfork

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:59:18