1.题目
Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into k non-empty subsets whose sums are all equal.
2.输入/输出样例
Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
Output: True
Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.
-
Note:
- 1 <= k <= len(nums) <= 16.
- 0 < nums[i] < 10000.
3.参考代码
class Solution {
public static boolean canPartitionKSubsets(int[] nums, int k) {
// 思路:典型的背包问题,但是每个数据仅使用一次,保证每个装包之和相等。
// 可对需要装包的数据排序,每次判断装包数据是否满足target(即平均值),来决定是否可装下去。
if (nums == null || nums.length == 0) {
return false;
}
if (k == 1) {
return true;
}
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % k != 0) {
return false;
}
boolean[] visited = new boolean[nums.length];
Arrays.sort(nums);
return dfs(nums, 0, nums.length - 1, visited, sum / k, k);
}
public static boolean dfs(int[] nums, int curSum, int startIndex, boolean[] visited, int target, int k) {
if(k==0){
return true;
}
// 满足当前curSum为target,且后续的剩下的数据能继续均分成k-1份
if(curSum==target&&dfs(nums,0,nums.length-1,visited,target,k-1)){
return true;
}
for(int i=startIndex;i>=0;--i){
if(!visited[i]&&curSum+nums[i]<=target){
visited[i]=true;
// 接着查找后面的数据,满足k次平分
if(dfs(nums,curSum+nums[i],i-1,visited,target,k)){
return true;
}
visited[i]=false;
}
}
return false;
}
}