public boolean canPartitionKSubsets(int[] nums, int k) {
int n=nums.length;
Arrays.sort(nums);
int sum=0;
for(int i=0;i<n;i++){
sum+=nums[i];
}
if(sum%k!=0) return false;//判断是否合法
int tar=sum/k;
boolean[] dp=new boolean[1<<n];//表示是否已经遍历过某状态,遇到已遍历状态一定不可行,如果可行那么第一次直接返回true
return dfs(nums,dp,(1<<n)-1,tar,0);
}
boolean dfs(int[] nums,boolean[] dp,int mark,int tar,int cur){
if(mark==0)//所有数都已经选择
return true;
if(dp[mark])//已经遍历过该状态,说明不可行
return false;
//每次从头开始,尝试选择一个数加入当前组
for(int i=0;i<nums.length;i++){
if((1<<i&mark)==0)//该数已经选择
continue;
if(nums[i]+cur>tar)//该数较大,后面的数一定不满足
break;
if(dfs(nums,dp,mark^(1<<i),tar,(cur+nums[i])%tar))//挑选下一个数
return true;
if(cur==0) return false;//如果结果为true,当前组第一个数不管选哪个都应为true,因为总能找到一个它所在的组,否则为false
}
dp[mark]=true;//该状态不可行
return false;
}
状态压缩+记忆化搜索leetcode.698
最新推荐文章于 2024-07-25 11:27:31 发布