前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021-08-02:按公因数计算最大组件大小。给定一个由不同正整数的组成的非空数组 A,考虑下面的图:有 A.length 个

2021-08-02:按公因数计算最大组件大小。给定一个由不同正整数的组成的非空数组 A,考虑下面的图:有 A.length 个

作者头像
福大大架构师每日一题
发布2021-08-05 16:32:34
5480
发布2021-08-05 16:32:34
举报

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

福大大 答案2021-08-02:

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

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

空间复杂度:O(N)。

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

代码语言:javascript
复制
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代码](https://github.com/algorithmzuo/coding-for-great-offer/blob/main/src/class20/Code02_LargestComponentSizebyCommonFactor.java)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 福大大架构师每日一题 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

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