2022-1-20DFSday2
题1:
给定一个整数数组 nums
和一个正整数 k
,找出是否有可能把这个数组分成 k
个非空子集,其总和都相等。
示例 1:
输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4 输出: True 说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。
提示:
1 <= k <= len(nums) <= 16
0 < nums[i] < 10000
1 class Solution { 2 public boolean canPartitionKSubsets(int[] nums, int k) { 3 int sum=0; 4 for (int num:nums) sum+=num; 5 if (sum%k!=0) return false; 6 int target=sum/k; 7 int[] count=new int[k]; 8 Arrays.sort(nums); 9 return backtrack(nums.length-1,count,nums,target); 10 } 11 12 13 public boolean backtrack(int index,int[] count,int[] nums,int target){ 14 if (index<0) { 15 //判断是否正确 16 //for (int x:count){ 17 // if (x!=target) return false; 18 //} 19 return true; 20 } 21 for (int i=0;i<count.length;i++) { 22 if (count[i]+nums[index]==target||count[i]+nums[index]+nums[0]<=target){ 23 count[i]+=nums[index]; 24 if (backtrack(index-1,count,nums,target)) return true; 25 count[i]-=nums[index]; 26 } 27 28 } 29 return false; 30 } 31 }
思路:枚举每个桶来装填数字,每次遍历所有数字,当前桶正好装下或者能装下当前并且还能装其他数字(即不存在装不满的情况),回溯搜索。状态压缩DP方法最优。