698. 划分为k个相等的子集
Java:回溯
class Solution {
boolean[] used;
int target;
private boolean backtracking(int[] nums, int k, int sum, int start) {
if (k == 0) {
return true; // 找到:立即中断栈!并返回值
}
if (sum == target) { // 构建下一个集合, return相当于把上一个dfs堆栈给掐掉
return backtracking(nums, k-1, 0, 0);
}
for (int i = start; i < nums.length; i++) { // 逐渐过滤已使用的数字,用剩下的数字重新回溯看能否构建
if (!used[i] && sum + nums[i] <= target) {
used[i] = true;
if (backtracking(nums, k, sum + nums[i], i + 1)) {
return true;
}
used[i] = false;
}
}
return false;
}
public boolean canPartitionKSubsets(int[] nums, int k) {
// 注意nums[i] > 0
int sum = 0, maxNum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
maxNum = Math.max(maxNum, nums[i]);
}
if (sum % k != 0 || maxNum > sum/k) {
return false;
}
used = new boolean[nums.length];
target = sum / k;
return backtracking(nums, k, 0, 0);
}
}