698.划分为k个相等的子集

196 阅读1分钟

题目:
给定一个整数数组  nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
算法:
先对nums求和,得到sum,sum % k != 0 必然不存在;
如果sum % k == 0,也不一定存在,比如nums=[6,4],sum=10, k=2。 x = sum / k = 5

算法一:dfs

func canPartitionKSubsets(nums []int, k int) bool {
	sum := 0 
	for i := range nums {
		sum = sum + nums[i]
	}
	if sum % k != 0 {
		return false
	}
	avg := sum / k
	sort.Ints(nums)
	if nums[len(nums) - 1] > avg {
		return false
	}
	n := len(nums)
	visited := make([]bool, 1 << n)
	for i := range visited {
		visited[i] = true
	}
	var dfs func(state, s int) bool 
	dfs = func(state, curSum int) bool {
		if state == 0 {
			return true
		}
		if !visited[state] {
			return false
		}
		visited[state] = false
		for i := 0; i < len(nums); i ++ {
			if curSum + nums[i] > avg {
				break
			}
			if state & (1 << i) == 0 {
				continue
			}
			if dfs(state & (^(1 << i)), (curSum + nums[i]) % avg) {
				return true
			}
		}
		return false
	}
	return dfs((1 << n) - 1, 0)
}