698. 划分为k个相等的子集
给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
搜索
import java.util.Arrays;
class Solution {
private boolean[] used;
private boolean solve(int[] nums, int index, int sum, int k, int target) {
if (k == 1) {
return true;
}
if (index == nums.length) {
return false;
}
boolean ret = false;
for (int i = index; i < nums.length && sum + nums[i] <= target; ++i) {
if (!used[i]) {
used[i] = true;
if (sum + nums[i] == target) {
ret = solve(nums, 0, 0, k - 1, target);
} else {
ret = solve(nums, i + 1, sum + nums[i], k, target);
}
used[i] = false;
if (ret) {
return true;
}
}
}
return false;
}
public boolean canPartitionKSubsets(int[] nums, int k) {
if (k == 1) {
return true;
}
int sum = Arrays.stream(nums).sum();
if (sum % k != 0) {
return false;
}
Arrays.sort(nums);
int target = sum / k;
if (nums[nums.length - 1] > target) {
return false;
}
this.used = new boolean[nums.length];
return solve(nums, 0, 0, k, target);
}
}
记忆化搜索
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
class Solution {
Map<Integer, Boolean> dp = new HashMap<>();
private boolean solve(int limit, int[] nums, int target, int sum) {
if (limit == 0) {
return true;
}
if (dp.containsKey(limit)) {
return dp.get(limit);
}
int bits = limit;
boolean ans = false;
while (bits > 0) {
int lowbit = bits & (-bits);
bits -= lowbit;
int index = (int) (Math.log(lowbit) / Math.log(2) + 0.5);
if (nums[index] + sum > target) {
break;
}
if (solve(limit ^ lowbit, nums, target, (sum + nums[index]) % target)) {
ans = true;
break;
}
}
dp.put(limit, ans);
return ans;
}
public boolean canPartitionKSubsets(int[] nums, int k) {
int sum = Arrays.stream(nums).sum();
if (sum % k != 0) {
return false;
}
sum /= k;
Arrays.sort(nums);
if (nums[nums.length - 1] > sum) {
return false;
}
return solve((1 << nums.length) - 1, nums, sum, 0);
}
}
心之所向,素履以往 生如逆旅,一苇以航

浙公网安备 33010602011771号