952. Largest Component Size by Common Factor

65 篇文章 0 订阅
11 篇文章 0 订阅

Given a non-empty array of unique positive integers A, consider the following graph:

  • There are A.length nodes, labelled A[0] to A[A.length - 1];
  • There is an edge between A[i] and A[j] if and only if A[i] and A[j] share a common factor greater than 1.

Return the size of the largest connected component in the graph.

 

Example 1:

Input: [4,6,15,35]
Output: 4

Example 2:

Input: [20,50,9,63]
Output: 2

Example 3:

Input: [2,3,6,7,4,12,21,39]
Output: 8

Note:

  1. 1 <= A.length <= 20000
  2. 1 <= A[i] <= 100000

思路:一开始想求出数组每个数之间是不是联通的,然后跑BFS,TLE

class Solution:
    def largestComponentSize(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        n=len(A)
        A.sort()
#        adj=[[False for _ in range(n)] for _ in range(n)]
        adj=[set() for _ in range(n)]
        for i in range(n):
            for j in range(i+1, n):
                a,b=A[i],A[j]
                while b%a: a,b=b%a,a
                if a>1: 
#                    adj[i][j]=True
                    adj[i].add(j)
                    adj[j].add(i)
        
        vis=[False]*n
        ma=0
        for i in range(n):
            if vis[i]: continue
            vis[i]=True
            q=[i]
            cnt=1
            while q:
                s=q.pop()
                for t in adj[s]:
                    if vis[t]: continue
                    q.append(t)
                    vis[t]=True
                    cnt+=1
            ma=max(ma,cnt)
            
        return ma
    
s=Solution()
print(s.largestComponentSize([4,6,15,35]))
print(s.largestComponentSize([20,50,9,63]))
print(s.largestComponentSize([2,3,6,7,4,12,21,39]))
#print(s.largestComponentSize(A))
                

然后就想,循环遍历数组的每个index pair似乎太慢,就是在bfs里面每次都是cnt+=1。

其实我们可以把所有的素数求出来,包含每个素数的数可以看成一个group,这样每次union联通在一起的素数,每次累加就是约数里含有该素数的所有数(也就是这个group里面的所有数)

那怎么判断哪些素数应该union起来呢,就是对每个数做素数分解,然后这个数对应的这些素数的group都应该union起来。

这里其实是角度的变换,之前是union数组A中不同index的数,现在是union素数group;之前union的判据是数组A中是不是有共同约数(外部计算),现在是数组A中每个数的素数约数两两之间就可以union(内部计算)

from collections import Counter

class Solution:
    def largestComponentSize(self, A):
        """
        :type A: List[int]
        :rtype: int
        """
        primes = []
        for t in A:
            prime = []
            p = 2
            while p*p<=t:
                if t%p==0:
                    while t%p==0:
                        t/=p
                    prime.append(p)
                p+=1
            if t>1 or not prime: prime.append(t) # t is a prime
            primes.append(prime)
        
        all_primes = list({p for prime in primes for p in prime})
        prime2group= {t:i for i,t in enumerate(all_primes)}
        
        # build adj first and run BFS
        # or just run union-find
        
        fa = list(range(len(all_primes)))
        def find(i):
            if fa[i]!=i: fa[i]=find(fa[i])
            return fa[i]
        def union(i,j):
            ii,jj=find(i),find(j)
            fa[ii]=jj
        
        for prime in primes:
            for p in prime:
                union(prime2group[prime[0]], prime2group[p])
                
        count = Counter(find(prime2group[prime[0]]) for prime in primes)
        return max(count.values())

    
s=Solution()
print(s.largestComponentSize([4,6,15,35]))
print(s.largestComponentSize([20,50,9,63]))
print(s.largestComponentSize([2,3,6,7,4,12,21,39]))
#print(s.largestComponentSize(A))
                

union-find也可以替换为BFS,只要预先求出哪些group要union就可以了

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值