Partition to K Equal Sum Subsets

10 篇文章 0 订阅
4 篇文章 0 订阅

[leetcode]Partition to K Equal Sum Subsets

链接:https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/

Question

Given an array of integers nums and a positive integer k, find whether it’s possible to divide this array into knon-empty subsets whose sums are all equal.

Example 1

Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
Output: True
Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.

Note:

1 <= k <= len(nums) <= 16.

0 < nums[i] < 10000.

Solution

class Solution {
public:
#define Pair pair<int, int>
  vector<int> nums;
  map<Pair, bool> mp;
  int ori_target;

  int getUseNum(vector<bool>& nums) {
    int use_num = 0;
    for (int i = 0; i < nums.size(); i++) {
      if (nums[i] == true)
        use_num += (1 << i);
    }
    return use_num;
  }

  bool search(vector<bool> used, int k, int target) {
    int use_num = getUseNum(used);
    if (mp.find(Pair(use_num, target)) != mp.end())
      return mp[Pair(use_num, target)];
    if (k == 1) return true;
    for (int i = 0; i < nums.size(); i++) {
      if (!used[i]) {
        used[i] = true;
        if (target - nums[i] > 0) {
          bool success = search(used, k, target-nums[i]);
          use_num = getUseNum(used);
          mp[Pair(use_num, target-nums[i])] = success;
          if (success) return true;
        } else if (target - nums[i] == 0) {
          bool success = search(used, k-1, ori_target);
          use_num = getUseNum(used);
          mp[Pair(use_num, target)] = success;
          if (success) return true;
        } else {
          break;
        }
        used[i] = false;
      }
    }
    use_num = getUseNum(used);
    mp[Pair(use_num, target)] = false;
    return false;
  }

  bool canPartitionKSubsets(vector<int>& nums, int k) {
    int sum = 0;
    for (int i = 0; i < nums.size(); i++) sum += nums[i];
    if (sum % k != 0) return false;
    int target = sum/k;
    ori_target = target;
    this->nums = nums;
    sort(this->nums.begin(), this->nums.end());
    vector<bool> used(nums.size(), false);

    return search(used, k, target);
  }
};

思路:使用dfs和回溯来解,注意要进行状态压缩。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值