952. Largest Component Size by Common Factor

思路过程:
看到题目的一瞬间觉得so easy,因为类似题目做到过好几次,leetcode上很多求最大连通子图大小之类的题目都可以用并查集来解决。(后来被妥妥打脸,花了一小时才搞定,555)
版本1:

class Solution {
public:
    unordered_map P; 
    unordered_map count;
    int findfather(int x){
        if(P.find(x) == P.end())
        {
            P[x] = x;
            count[x] = 1;
        }
        if(P[x] != x)
            P[x] = findfather(P[x]);
        return P[x];
    }
    
    void togather(int x,int y){
        int px = findfather(x);
        int py = findfather(y);
        if(pxpy){
           count[py] += count[px];
            P[px] = py;
        }
    }
    
    void count_number(int x,set &temp){
    //分解质因数
        int n =2;
        while(n<=x){
            while(x%n == 0){
                x = x/n;
                temp.insert(n);
            }
            n+=1;
        }
    }
    
    int largestComponentSize(vector& A) {
        unordered_map factormap;
        for(auto a :A){
            set temp;
            count_number(a,temp);
            int x = a,y = a;
            for(auto b : temp){
                if(factormap.find(b) != factormap.end()){
                    y = factormap[b];
                    togather(x,y);
                }else
                    factormap[b] = a;
            }
        }
        int maxcount = 0;
        for(unordered_map::iterator it = count.begin();it!=count.end();it++)
            maxcount = max(maxcount,(*it).second);
        return maxcount;
    }
};

提交后,果不其然的Boom 爆炸了。查找可以优化的地方:1.最后的循环查找最大count是可以在每次togather中完成;2.分解质因数的过程和归并过程可以放在一起;3.可以开一个set来存放所有可能的质数。
第一次修改后的代码:

class Solution {
public:
    unordered_map P; 
    unordered_map count;
    int maxcount = 0;
    int findfather(int x){
        if(P.find(x) == P.end())
        {
            P[x] = x;
            count[x] = 1;
        }
        if(P[x] != x)
            P[x] = findfather(P[x]);
        return P[x];
    }
    
    void togather(int x,int y){
        int px = findfather(x);
        int py = findfather(y);
        if(px!=py){
           count[py] += count[px];
           P[px] = py;
           maxcount = max(maxcount,count[py]);
        }
    }
    
    int largestComponentSize(vector& A) {
        unordered_map factormap;
        vector prime(100001,1);
        set isp;//存放质数
        for(int i =2;i<100001;i++)
        {
            if(prime[i] != 0)
                isp.insert(i);
            for(int j = 2;j*i<100001;j++)
                prime[i*j] = 0;
        }
        for(auto a :A){
            for(set::iterator it = isp.begin();(it!=isp.end())&& ((*it)<= a);it++)
            {
                if(a % (*it) == 0)
                {
                    if(factormap.find((*it)) != factormap.end())
                        togather(a,factormap[(*it)]);
                    else
                        factormap[(*it)] = a;
                }
            }
            }
        return maxcount;
    }
};

还是Time Limit Exceeded.emmmm,换一种判断分解质因数过程结束的方法
修改后的代码:

class Solution {
public:
    unordered_map P; 
    unordered_map count;
    int maxcount = 0;
    int findfather(int x){
        if(P.find(x) == P.end())
        {
            P[x] = x;
            count[x] = 1;
        }
        if(P[x] != x)
            P[x] = findfather(P[x]);
        return P[x];
    }
    
    void togather(int x,int y){
        int px = findfather(x);
        int py = findfather(y);
        if(px!=py){
           count[py] += count[px];
           P[px] = py;
           maxcount = max(maxcount,count[py]);
        }
    }
    
    int largestComponentSize(vector& A) {
        unordered_map factormap;
        vector prime(100001,1);
        set isp;
        for(int i =2;i<100001;i++)
        {
            if(prime[i] != -1)
                isp.insert(i);
            for(int j = 1;j*i<100001;j++)
                prime[i*j] = -1;
        }
        for(auto a :A){
            int y = a;
            for(set::iterator it = isp.begin();(it!=isp.end())&& y>1;it++)
            {
                int x = *it;
                if(y % x == 0)
                {
                    if(factormap.find(x) != factormap.end())
                        togather(a,factormap[x]);
                    else
                    {
                        factormap[x] = a;
                    }
                    while(y%x == 0)
                        y /= x;
                }
            }
            }
        return maxcount;
    }
};

emmm,依旧爆炸,实在想不出,然后看了大佬对于分解质因数过程的优化
代码:

class Solution {
public:
    unordered_map P; 
    unordered_map count;
    int maxcount = 0;
    int findfather(int x){
        if(P.find(x) == P.end())
        {
            P[x] = x;
            count[x] = 1;
        }
        if(P[x] != x)
            P[x] = findfather(P[x]);
        return P[x];
    }
    
    void togather(int x,int y){
        int px = findfather(x);
        int py = findfather(y);
        if(px!=py){
           count[py] += count[px];
           P[px] = py;
           maxcount = max(maxcount,count[py]);
        }
    }
    
    int largestComponentSize(vector& A) {
        unordered_map factormap;
        vector prime(100001,1);
        set isp;
        for(int i =2;i<100001;i++)
        {
            if(prime[i] != -1)
                isp.insert(i);
            for(int j = 1;j*i<100001;j++)
                prime[i*j] = -1;
        }
        for(auto a :A){
            int y = a;
            for(set::iterator it = isp.begin();(it!=isp.end())&& y>1;it++)
            {
                int x = isp.find(y)==isp.end()?*it:y;//主要改了这里,减少循环次数
                if(y % x == 0)
                {
                    if(factormap.find(x) != factormap.end())
                        togather(a,factormap[x]);
                    else
                    {
                        factormap[x] = a;
                    }
                    while(y%x == 0)
                        y /= x;
                }
            }
            }
        return maxcount;
    }
};

通过啦,runtime 480 ms
——————————————
然后发现prime似乎可以用来代替factormap
修改后的代码:

class Solution {
public:
    unordered_map P; 
    unordered_map count;
    int maxcount = 0;
    int findfather(int x){
        if(P.find(x) == P.end())
        {
            P[x] = x;
            count[x] = 1;
        }
        if(P[x] != x)
            P[x] = findfather(P[x]);
        return P[x];
    }
    
    void togather(int x,int y){
        int px = findfather(x);
        int py = findfather(y);
        if(px!=py){
           count[py] += count[px];
           P[px] = py;
           maxcount = max(maxcount,count[py]);
        }
    }
    
    int largestComponentSize(vector& A) {
        vector prime(100001,1);
        set isp;
        for(int i =2;i<100001;i++)
        {
            if(prime[i] != -1)
                isp.insert(i);
            for(int j = 1;j*i<100001;j++)
                prime[i*j] = -1;
        }
        for(auto a :A){
            int y = a;
            for(set::iterator it = isp.begin();(it!=isp.end())&& y>1;it++)
            {
                int x = isp.find(y)==isp.end()?*it:y;
                if(y % x == 0)
                {
                    if(prime[x]!= -1)
                        togather(a,prime[x]);
                    else
                    {
                        prime[x] = a;
                    }
                    while(y%x == 0)
                        y /= x;
                }
            }
            }
        return maxcount;
    }
};

runtime 452 ms

你可能感兴趣的:(952. Largest Component Size by Common Factor)