Leecode no.698 划分为k个相等的子集

package leecode;

/**
* 698. 划分为k个相等的子集
* 给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
*
*
* @author Tang
* @date 2021/12/10
*/
public class CanPartitionKSubsets {

int[] nums;

int[] bucket;

int target;

/**
* 通过回溯 实现穷举
* 穷举直到满足所有总和相等 或者失败
*
* @param nums
* @param k
* @return
*/
public boolean canPartitionKSubsets(int[] nums, int k) {
this.nums = nums;
//创建k个桶
this.bucket = new int[k];

//创建每个桶的目标值
//因为nums平均分给k个桶
for (int num : nums) {
target+=num;
}
target = target / k;

return track(0);

}

/**
* 挨个元素判断,
* 递归桶,判断当前元素该不该入桶
*
* @param index 当前玩第几个元素
*/
private boolean track(int index) {
//元素到头了
if(index == nums.length) {
int temp = bucket[0];
for (int b : bucket) {
//只要有一个元素不和第一个元素相同就说明不全相等
if (b != temp) {
return false;
}
}
return true;
}

//循环桶 判断当前元素该不该加入这个桶
for(int i = 0; i < bucket.length; i++) {
//剪枝 超过桶正常大小的不要再递归算了
if(bucket[i] > target) {
continue;
}

//递归前做出选择
//入桶
bucket[i] = bucket[i] + nums[index];

//执行递归 去玩下一个元素
boolean track = track(index + 1);
if(track) {
//减少剩余的操作
return true;
}

//递归后撤销选择
bucket[i] = bucket[i] - nums[index];
}
return false;

}

public static void main(String[] args) {

}
}
posted @ 2021-12-10 17:58  六小扛把子  阅读(30)  评论(0编辑  收藏  举报