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

Go实现LeetCode 2493超时求助:代码正确但运行过慢

LeetCode 2493题Go代码超时问题

我是物理专业出身的系统管理员,靠兴趣自学编程。我的Go代码能正确解决LeetCode 2493题,但存在运行超时的问题。

解题思路

  • 使用**并查集(Union-Find)**算法找出图中所有连通子图;
  • 对每个连通子图,以每个顶点为根构建BFS树,获取最大深度,同时验证图是否为二分图。

核心逻辑代码

func magnificentSets(n int, edges [][]int) int {
    // 构建图
    g := GraphWithCapacity(n)
    set := DisjointSetWiithCapacity(n)
    for _, e := range edges {
        src := e[0] - 1
        dst := e[1] - 1
        if !g.AddEdge(src, dst) {
            fmt.Printf("无法添加边 {%d, %d}\n.", src, dst)
        }
        set.Union(src, dst)
    }

    connected_subgraphs := make(map[int][]int)
    for n := range g.EachNode() {
        p := set.Find(n)
        connected_subgraphs[p] = append(connected_subgraphs[p], n)
    }
    total_maxdepths := 0

    for _, vlist := range connected_subgraphs {
        if len(vlist) == 1 {
            total_maxdepths += 1
            continue
        }

        maxdepth := 0
        for _, v := range vlist {
            _, depthatv, err := bfs(g, v)
            if err != nil {
                fmt.Println(err.Error())
                return -1
            }

            if depthatv > maxdepth {
                maxdepth = depthatv
            }

        }

        total_maxdepths += maxdepth + 1
    }

    return total_maxdepths
}

代码拆分说明

并查集实现

type disjoint_set struct {
    parent []int
}

func DisjointSetWiithCapacity(n int) disjoint_set {
    parent := make([]int, n)
    for idx := range parent {
        parent[idx] = idx
    }

    return disjoint_set{parent}
}

func (uf *disjoint_set) Find(node int) int {
    cnode := node

    for uf.parent[cnode] != cnode {
        cnode = uf.parent[cnode]
    }
    uf.parent[node] = cnode
    return cnode
}
func (uf *disjoint_set) Union(node_1, node_2 int) bool {
    p1 := uf.Find(node_1)
    p2 := uf.Find(node_2)
    if p1 == p2 {
        return false
    }

    child := max(p1, p2)
    parent := min(p1, p2)
    uf.parent[child] = parent
    return true
}

图数据结构实现

type ErrNodeNotFound struct {
    nodeid int
}

func (e ErrNodeNotFound) Error() string {
    return fmt.Sprintf("图中未找到节点 %d。\n", e.nodeid)
}

type graph struct {
    fadjlist [][]int
}

func GraphWithCapacity(cap int) graph {
    return graph{fadjlist: make([][]int, cap)}
}

图操作方法

func (g *graph) AddNode() int {
    g.fadjlist = append(g.fadjlist, make([]int, 0))
    return len(g.fadjlist) - 1
}
func (g *graph) HasNode(nodeid int) bool {
    return nodeid < len(g.fadjlist)
}
func (g *graph) EachNode() iter.Seq[int] {
    return func(yield func(int) bool) {
        for i := 0; i < len(g.fadjlist); i += 1 {
            if !yield(i) {
                return
            }
        }
    }
}
func (g *graph) EachEdge() iter.Seq2[int, int] {
    return func(yield func(int, int) bool) {
        for src, adjlist := range g.fadjlist {
            for _, dst := range adjlist {
                if dst > src {
                    continue
                }

                if !yield(src, dst) {
                    return
                }
            }
        }
    }
}
func (g *graph) AddEdge(from, to int) bool {
    src := min(from, to)
    dst := max(from, to)
    if !g.HasNode(src) || !g.HasNode(dst) {
        return false
    }

    if slices.Contains(g.fadjlist[src], dst) {
        return false
    }

    g.fadjlist[src] = append(g.fadjlist[src], dst)
    g.fadjlist[dst] = append(g.fadjlist[dst], src)

    return true
}
func (g *graph) Neighbours(nodeid int) ([]int, error) {
    if !g.HasNode(nodeid) {
        return []int{}, ErrNodeNotFound{nodeid}
    }

    return g.fadjlist[nodeid], nil
}

元图结构及操作

type bfsdata struct {
    Color int
    Depth int
}

type metagraph[T any] struct {
    G        *graph
    metadata map[int]T
}
func (mg *metagraph[T]) Data(v int) (T, error) {
    if !mg.G.HasNode(v) {
        return mg.metadata[v], ErrNodeNotFound{v}
    }

    return mg.metadata[v], nil
}
func (mg *metagraph[T]) SetData(v int, data T) (T, error) {
    if !mg.G.HasNode(v) {
        return mg.metadata[v], ErrNodeNotFound{v}
    }

    mg.metadata[v] = data
    return mg.metadata[v], nil
}

BFS核心逻辑

func ProcessChildren(mg metagraph[bfsdata], parent int, checked map[int]bool) bool {
    children, e := mg.G.Neighbours(parent)
    if e != nil {
        panic(e)
    }

    mydata, err := mg.Data(parent)
    if err != nil {
        return false
    }

    for _, child := range children {
        if checked[child] {
            continue
        }

        childdata, e := mg.Data(child)
        if e != nil {
            return false
        } else if childdata.Color == mydata.Color {
            return false
        }

        mg.SetData(child, bfsdata{Color: -1 * mydata.Color, Depth: mydata.Depth + 1})

    }

    return true
}


type ErrNotBipartite struct {
    parent int
}

func (e ErrNotBipartite) Error() string {
    return fmt.Sprintf("节点 %d 与同一分区的节点相连", e.parent)
}

func bfs(g graph, root int) (metagraph[bfsdata], int, error) {
    mg := metagraph[bfsdata]{&g, make(map[int]bfsdata)}
    mg.SetData(root, bfsdata{Color: -1, Depth: 0})

    // 以第一个节点为根启动BFS
    tocheck := []int{root}
    maxdepth := 0
    _, e := mg.G.Neighbours(root)
    if e != nil {
        panic(e)
    }
    checked := make(map[int]bool)

    for len(tocheck) > 0 {
        checkme := tocheck[0]
        tocheck = tocheck[1:]

        if checked[checkme] {
            continue
        }

        if !ProcessChildren(mg, checkme, checked) {
            return mg, -1, ErrNotBipartite{checkme}
        }

        mydata, _ := mg.Data(checkme)
        if maxdepth < mydata.Depth {
            maxdepth = mydata.Depth
        }
        nlist, _ := mg.G.Neighbours(checkme)
        tocheck = append(tocheck, nlist...)
        checked[checkme] = true
    }

    return mg, maxdepth, nil
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:17:04