https://leetcode.com/problems/gcd-sort-of-an-array/
方法还是很巧妙的,也很考验编程的基本功,记下来备忘。
个人题解
func gcdSort(nums []int) bool {set := make(map[int]int)for _, x := range(nums) {// 遍历所有x的primeFactor,union起来xx := xfor p := 2; p * p <= xx; p++ {if xx % p == 0 {setUnion(set, x, p)for xx % p == 0 {xx /= p}}}// x是素数的情况下,其本身也是primeFactorif xx != 1 {setUnion(set, x, xx)}}sorted := make([]int, len(nums))copy(sorted, nums)sort.Ints(sorted)for i,_ := range(nums) {r1, r2 := setFind(set, sorted[i]), setFind(set, nums[i])if r1 != r2 {return false}}return true}func setFind(set map[int]int, x int) int {if v, ok := set[x]; ok {if v < 0 {return x}set[x] = setFind(set, v)return set[x]} else {set[x] = -1return x}}func setUnion(set map[int]int, x int, y int) {rx := setFind(set, x)ry := setFind(set, y)if rx == ry {return}if set[rx] < set[ry] {set[rx] += set[ry]set[ry] = rx} else {set[ry] += set[rx]set[rx] = ry}}
题目分析
这道题的其中一个考点,并查集,应该比较容易想到,只有当前的元素和目标的元素(排序好之后对应的元素)能够互换,才能够打到最终的目标。
那么问题转化为,union的条件是什么呢?题目中给的很直接,两个数不互质。
可是两两计算GCD,用辗转相除法,复杂度太高,这就太难办了。
那么可以找一个中间量,就是每个数的primeFactors,每个数和其所有的primeFactors都可以union,如此通过primeFactors作为桥梁,不互质的数也都union了起来,妙呀妙呀。
具体的优雅实现可能还需要一些trick,直接看代码吧。
