Given an integer array nums and an integer k, return true if it is possible to divide this array into k non-empty subsets whose sums are all equal.
This is leetcode problem #698.
Below is code that I have written with backtracking to solve the problem (it is correct and passes all test cases).
When we apply memoization for a DP solution shouldn't the current state we are in for memoization depend on all of: currSum, count, and taken? Instead, all we need is taken and not currSum and count to uniquely identify our state.
For clarification: taken tells us which numbers we've selected thus far (or havent selected), count tells us the number of subsets we've currently divided into subsets, and currSum tells us the current sum for the subset we're trying to solve.
So why do we only need taken to identify the memoization state, and not all of taken and count and currSum?
class Solution {
bool helper(const vector<int>& nums, int k, int count, int currSum, int targetSum, int index, vector<int>& taken) {
if (count == k - 1)
return true;
if (currSum > targetSum)
return false;
if (currSum == targetSum)
return helper(nums, k, count + 1, 0, targetSum, 0, taken);
for (int i = index; i < nums.size(); i++) {
if (!taken[i]) {
taken[i] = 1;
if (helper(nums, k, count, currSum + nums[i], targetSum, i + 1, taken))
return true;
taken[i] = 0;
}
}
return false;
}
public:
bool canPartitionKSubsets(vector<int>& nums, int k) {
sort(nums.begin(), nums.end(), greater<>());
vector<int> taken(nums.size(), 0);
const int sum = accumulate(nums.begin(), nums.end(), 0);
if (sum % k != 0 || *max_element(nums.begin(), nums.end()) > sum / k)
return false;
return k == 1 || helper(nums, k, 0, 0, sum / k, 0, taken);
}
};