前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021-08-02:按公因数计算最大组件大小。给定一个由不同

2021-08-02:按公因数计算最大组件大小。给定一个由不同

原创
作者头像
福大大架构师每日一题
修改2021-08-03 10:08:53
4360
修改2021-08-03 10:08:53
举报
文章被收录于专栏:福大大架构师每日一题

2021-08-02:按公因数计算最大组件大小。给定一个由不同正整数的组成的非空数组 A,考虑下面的图:有 A.length 个节点,按从 A0 到 AA.length - 1 标记;只有当 Ai 和 Aj 共用一个大于 1 的公因数时,Ai 和 Aj 之间才有一条边。返回图中最大连通组件的大小。

福大大 答案2021-08-02:

算出每个的公因数,然后并查集。

时间复杂度: O(N*sqrt(V))。

空间复杂度: O(N)。

代码用golang编写。代码如下:

代码语言:txt
复制
package main

import (
    "fmt"
    "math"
)

func main() {
    arr := []int{2, 3, 6, 7, 4, 12, 21, 39}
    ret := largestComponentSize2(arr)
    fmt.Println(ret)
}
func largestComponentSize2(arr []int) int {
    N := len(arr)
    // arr中,N个位置,在并查集初始时,每个位置自己是一个集合
    unionFind := NewUnionFind(N)
    //      key 某个因子   value 哪个位置拥有这个因子
    fatorsMap := make(map[int]int)
    for i := 0; i < N; i++ {
        num := arr[i]
        // 求出根号N, -> limit
        limit := int(math.Sqrt(float64(num)))
        for j := 1; j <= limit; j++ {
            if num%j == 0 {
                if j != 1 {

                    if _, ok := fatorsMap[j]; !ok {
                        fatorsMap[j] = i
                    } else {
                        unionFind.union(fatorsMap[j], i)
                    }
                }
                other := num / j
                if other != 1 {
                    if _, ok := fatorsMap[other]; !ok {
                        fatorsMap[other] = i
                    } else {
                        unionFind.union(fatorsMap[other], i)
                    }
                }
            }
        }
    }
    return unionFind.maxSize()
}

// O(1)
// m,n 要是正数,不能有任何一个等于0
func gcd(a int, b int) int {
    if b == 0 {
        return a
    } else {
        return gcd(b, a%b)
    }
}

type UnionFind struct {
    parents []int
    sizes   []int
    help    []int
}

func NewUnionFind(N int) *UnionFind {
    res := &UnionFind{}
    res.parents = make([]int, N)
    res.sizes = make([]int, N)
    res.help = make([]int, N)
    for i := 0; i < N; i++ {
        res.parents[i] = i
        res.sizes[i] = 1
    }
    return res
}

func (this *UnionFind) maxSize() int {
    ans := 0
    for _, size := range this.sizes {
        ans = getMax(ans, size)
    }
    return ans
}

func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

func (this *UnionFind) find(i int) int {
    hi := 0
    for i != this.parents[i] {
        this.help[hi] = i
        hi++
        i = this.parents[i]
    }
    for hi--; hi >= 0; hi-- {
        this.parents[this.help[hi]] = i
    }
    return i
}

func (this *UnionFind) union(i int, j int) {
    f1 := this.find(i)
    f2 := this.find(j)
    if f1 != f2 {
        big := twoSelectOne(this.sizes[f1] >= this.sizes[f2], f1, f1)
        small := twoSelectOne(big == f1, f2, f1)
        this.parents[small] = big
        this.sizes[big] = this.sizes[f1] + this.sizes[f2]
    }
}

func twoSelectOne(c bool, a int, b int) int {
    if c {
        return a
    } else {
        return b
    }
}

执行结果如下:

图片
图片

左神java代码

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档