LeetCode——698.划分位k个相等的子集

大佬,牛!!!

  • 题目:给你一个数组,然后看一下这个数组的数能不能平均分到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];
        }
    }
}
  • 总结:对我来说,题目还是比较难的,其实大佬的思路我想到过,但是写不出来。太难了,哎。

你可能感兴趣的:(算法,leetcode,算法,java,动态规划,位运算)