Question
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.
Example 1:
Input: nums = [4,3,2,3,5,2,1], k = 4 Output: true Explanation: It is possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.
Example 2:
Input: nums = [1,2,3,4], k = 3 Output: false
Constraints:
1 <= k <= nums.length <= 16
1 <= nums[i] <= 10^4
- The frequency of each element is in the rangeÂ
[1, 4]
.
Solution:
class Solution {
public boolean canPartitionKSubsets(int[] nums, int k) {
// Calculate the total sum of the array elements
int sum = Arrays.stream(nums).sum();
boolean[] used = new boolean[nums.length];
// If total sum is not divisible by k, partitioning into k subsets is impossible
if (sum % k != 0) {
return false;
}
// Sort the array to help with pruning and start with larger numbers
Arrays.sort(nums);
// Start the DFS search to partition the array into k subsets with sum sum/k
return dfs(nums, k, 0, 0, used, sum / k);
}
boolean dfs(int[] nums, int k, int currSum, int idx, boolean[] used, int target) {
// Base case: if only 1 subset is needed, the rest of the elements must already form a valid subset
if (k == 1) {
return true;
}
// If the current subset sum matches the target, move on to form the next subset
if (currSum == target) {
return dfs(nums, k - 1, 0, 0, used, target);
}
// Try to form the current subset by adding elements from nums
for (int i = idx; i < nums.length; i++) {
// Skip if the element is already used or if it leads to redundant checks (skip duplicates)
if (used[i] || i > 0 && nums[i] == nums[i - 1] && !used[i - 1]) {
continue;
}
// Mark the current element as used
used[i] = true;
// Recursively try to form the subset by including nums[i]
if (dfs(nums, k, currSum + nums[i], i + 1, used, target)) {
return true;
}
// Backtrack if the current element doesn't lead to a solution
used[i] = false;
}
// If no valid partitioning is found, return false
return false;
}
}