You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2023_05_2_week;
import java.util.Arrays;
// 给定一个整数数组 nums 和一个正整数 k
// 找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
// 测试链接 : https://leetcode.cn/problems/partition-to-k-equal-sum-subsets/
public class Code04_PartitionToKEqualSumSubsets {
// 状态压缩的方法,正统,处理不了大长度
// 其实任何方法都处理不了
public static boolean canPartitionKSubsets1(int[] nums, int k) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % k != 0) {
return false;
}
return process1(nums, 0, 0, 0, sum / k, k, new int[1 << nums.length]) == 1;
}
public static int process1(int[] nums, int status, int sum, int sets, int limit, int k, int[] dp) {
if (dp[status] != 0) {
return dp[status];
}
int ans = -1;
if (sets == k) {
ans = 1;
} else {
for (int i = 0; i < nums.length; i++) {
if ((status & (1 << i)) == 0 && sum + nums[i] <= limit) {
if (sum + nums[i] == limit) {
ans = process1(nums, status | (1 << i), 0, sets + 1, limit, k, dp);
} else {
ans = process1(nums, status | (1 << i), sum + nums[i], sets, limit, k, dp);
}
if (ans == 1) {
break;
}
}
}
}
dp[status] = ans;
return ans;
}
public static boolean canPartitionKSubsets2(int[] nums, int k) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % k != 0) {
return false;
}
Arrays.sort(nums);
return partitionK(new int[k], sum / k, nums, nums.length - 1);
}
// 100 10 -> 10
// 100 2 -> 50
// 100 4 -> 25
// 当前的数字nums[index]
// nums[n-1] 给哪个桶
// nums[n-2] 给哪个桶
// ...
// nums[0] 给哪个桶
public static boolean partitionK(int[] group, int target, int[] nums, int index) {
if (index < 0) {
return true;
}
int num = nums[index];
// len是桶的数量! 就是k
int len = group.length;
for (int i = 0; i < len; i++) {
if (group[i] + num <= target) {
// 放入后,不超
group[i] += num;
if (partitionK(group, target, nums, index - 1)) {
return true;
}
group[i] -= num;
// if (group[i] == 0) {
// return false;
// }
while (i + 1 < group.length && group[i] == group[i + 1]) {
i++;
}
}
}
return false;
}
}