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);
    }
}
posted @ 2021-12-19 16:35  Tianyiya  阅读(54)  评论(0)    收藏  举报