Skip to content

Latest commit

 

History

History
101 lines (81 loc) · 2.43 KB

0698.md

File metadata and controls

101 lines (81 loc) · 2.43 KB

Partition to K Equal Sum Subsets

题目

Given an integer array nums and an integer k, return true if it is possible to divide this array into k non-empty subsets whose sums are all equal.

Example 1:
Input: nums = [4,3,2,3,5,2,1], k = 4
Output: true
Explanation: It is possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.

Example 2:
Input: nums = [1,2,3,4], k = 3
Output: false
 

Constraints:
1 <= k <= nums.length <= 16
1 <= nums[i] <= 104
The frequency of each element is in the range [1, 4].

思路

题意:
给定一个数组,和k值
把数组拆分成k个数组,每个数组的sum值相等。
总的sum值可以计算出来,k也是知道的,所以单个数组的sum值也是知道的。所以也就是求收否可以才分成k个数组,每个数组都等于sum(one slice).已知

这种往数组中填值的题目一般都是使用回溯法

回溯法:
回溯函数的入参是数组和index,空值可选集合。
还有当前sum值cur,以及目标sum值target
每一层遍历可选集合,只要cur+nums[i] 小于等于target的就可以走向下一层。

回溯出口:index>len(nums) 表示有解,走到了最深处。

剪枝优化:对于某一层回溯函数而言,如果选择了nums[i]无解,那么当选择nums[i+1]时,就不需要再考虑nums[i]了。
需要需要设置一个cache,存储nums[i],当满足一个子数组时往下层走则清空。

代码

func canPartitionKSubsets(nums []int, k int) bool {
	sum, max := 0, 0
	for _, num := range nums {
		if num > max {
			max = num
		}
		sum += num
	}
	n := sum / k
	if n*k != sum || max > n {
		return false
	}
	return backTrack(nums, 0, 0, n, make(map[int]bool, len(nums)))
}

func backTrack(nums []int, index int, cur, target int, cache map[int]bool) bool {
	if index >= len(nums) {
		return true
	}
	if cur == target {
		cur = 0
	}
	for i := index; i < len(nums); i++ {
		if cache[nums[i]] {
			continue
		}
		temp := cur + nums[i]
		if temp <= target {
			nums[i], nums[index] = nums[index], nums[i]
			res := false
			if temp == target {
				res = backTrack(nums, index+1, temp, target, make(map[int]bool))
			} else {
				mp := make(map[int]bool, len(cache))
				for k := range cache {
					mp[k] = true
				}
				res = backTrack(nums, index+1, temp, target, mp)
			}
			if res {
				return true
			}
			nums[index], nums[i] = nums[i], nums[index]
		}
		cache[nums[i]] = true
	}
	return false
}