给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
示例 1:
输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
输出: True
说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。
思路:用now[k]代表目前k组元素的和分别是多少,对于每个nums[i]枚举分到0-k-1组,直到每个元素都被分完看看是否能够满足题意。
这个想法并不够快,如果不加剪枝甚至会超时,于是加了一个简单的剪枝,分配每个元素时,看看还有多少组元素和没有达到目标要求,如果有m组未达标,现在只有n个元素未分配,且m>n,那么这组分配必然不满足要求,直接返回false即可。
class Solution {
int now[] = new int [20];//每个集合目前的元素和
int l;
int sum;
public boolean dfs(int[] nums,int n,int k)
{
int cnt = 0;
for(int i=0;i<k;i++)
{
if(now[i]!=sum)
cnt++;
}
if(cnt>l-n)//简单剪枝
return false;
if(n==l)
{
for(int i=0;i<k;i++)
{
if(now[i]!=sum)
return false;
}
return true;
}
for(int i=0;i<k;i++)
{
if(nums[n]+now[i]<=sum)
{
now[i]+=nums[n];
boolean seven = dfs(nums,n+1,k);
if(seven)
return true;
now[i]-=nums[n];
}
}
return false;
}
public boolean canPartitionKSubsets(int[] nums, int k) {
l = nums.length;
sum = 0;
for(int i=0;i<l;i++)
sum+=nums[i];
if(sum%k!=0)
return false;
sum/=k;
return dfs(nums,0,k);
}
}