给你一个整数数组 nums ,你可以在 nums 上执行下述操作 任意次 :

如果 gcd(nums[i], nums[j]) > 1 ,交换 nums[i] 和 nums[j] 的位置。其中 gcd(nums[i], nums[j]) 是 nums[i] 和 nums[j] 的最大公因数。
如果能使用上述交换方式将 nums 按 非递减顺序 排列,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [7,21,3]
输出:true
解释:可以执行下述操作完成对 [7,21,3] 的排序:

  • 交换 7 和 21 因为 gcd(7,21) = 7 。nums = [21,7,3]
  • 交换 21 和 3 因为 gcd(21,3) = 3 。nums = [3,7,21]
    示例 2:

输入:nums = [5,2,6,2]
输出:false
解释:无法完成排序,因为 5 不能与其他元素交换。
示例 3:

输入:nums = [10,5,9,3,15]
输出:true
解释:
可以执行下述操作完成对 [10,5,9,3,15] 的排序:

  • 交换 10 和 15 因为 gcd(10,15) = 5 。nums = [15,5,9,3,10]
  • 交换 15 和 3 因为 gcd(15,3) = 3 。nums = [3,5,9,15,10]
  • 交换 10 和 15 因为 gcd(10,15) = 5 。nums = [3,5,9,10,15]

java代码:

class UnionFind
{
    int [] parent;
    int [] size;

    UnionFind(int n)
    {
        parent = new int [n];
        size = new int [n];
        for (int x = 0; x < n; x ++)
            parent[x] = x;
        Arrays.fill(size, 1);
    }

    public int Find(int x)
    {
        if (parent[x] != x)
            parent[x] = Find(parent[x]);
        return parent[x];
    }

    public boolean Union(int x, int y)
    {
        int root_x = Find(x);
        int root_y = Find(y);
        if (root_x == root_y)
            return false;
        if (size[root_x] > size[root_y])
        {
            int tmp = root_x;
            root_x = root_y;
            root_y = tmp;
        }
        parent[root_x] = root_y;
        size[root_y] += size[root_x];
        return true;
    }

    public boolean connected(int x, int y)
    {
        return Find(x) == Find(y);
    }

}


class Solution 
{
    public boolean gcdSort(int[] nums) 
    {
        int N = 100010;
        UnionFind UF = new UnionFind(N);

        int n = nums.length;
        for (int x : nums)
        {
            int a = 2;
            while (a * a <= x)
            {
                if (x % a == 0)
                {
                    int b = x / a;
                    UF.Union(x, a);
                    UF.Union(x, b);
                }
                a ++;
            }
        }

        int [] tar = Arrays.copyOfRange(nums, 0, n);
        Arrays.sort(tar);
        for (int i = 0; i < n; i ++)
        {
            int x = nums[i];
            int y = tar[i];
            if (UF.connected(x, y) == false)
                return false;
        }
        return true;

    }
}