大佬,牛!!!
- 题目:给你一个数组,然后看一下这个数组的数能不能平均分到k个集合中。要求k个集合的和是一样的。
- 我的思路:我没想到很好的方法,但是感觉暴力做有点太弱智,如果暴力做的话,最好是先用大的数据,然后再用小的。然后就是两种比不可能的情况,第一种是sum不能被k整除,第二种就是最大值大于avg=sum/k。
- 大佬思路:大佬的思路是动态规划,然后用上位运算符,说实话,位运算我还是不是特别熟练。其实跟之前的题目有点相似的。就是0-2的n次方个数,分别表示不同的情况,然后dp记录这个idx位置的情况行不行,然后再用一个数组记录如果行的话,值是多少。这里注意,值只要是小于avg的就表示可以。
- 技巧:动态规划、位运算
java代码
class Solution {
public boolean canPartitionKSubsets(int[] nums, int k) {
int sum = Arrays.stream(nums).sum();
if (sum % k != 0) {// 不能均分
return false;
}
int avg = sum / k;
Arrays.sort(nums);
int n = nums.length;
if (nums[n - 1] > avg) {// 最大值超过
return false;
}
boolean[] dp = new boolean[1 << n];
int[] curSum = new int[1 << n];
dp[0] = true;
// 遍历所有的情况
for (int i = 0; i < 1 << n; i++) {
if (!dp[i]) {// 这个情况,已经出现过了
continue;
}
// 遍历所有的数
for (int j = 0; j < n; j++) {
if (curSum[i] + nums[j] > avg) {
break;
}
if (((i >> j) & 1) == 0) {// i标记的这个下标下,j可以被使用
int next = i | (1 << j);
if (!dp[next]) {// 使用上j以后,现在的值是多少,并且将dp设置为true
curSum[next] = (curSum[i] + nums[j]) % avg;
dp[next] = true;
}
}
}
return dp[(1 << n) - 1];
}
}
}
- 总结:对我来说,题目还是比较难的,其实大佬的思路我想到过,但是写不出来。太难了,哎。