[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 k
non-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和回溯来解,注意要进行状态压缩。