Description
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
给一个数组,问数组中的元素能否被分为k个子集,每个子集的和都是相同的。
If we want divide nums into k different subarray with same sum value. sum of nums % k == 0
is required. So we count the sum value first. Then maintain a visited array to perform DFS to find if can partition.
Assume sum
is the sum of nums[]
. The dfs process is to find a subset of nums[]
which sum equals to sum/k
. We use an array visited[]
to record which element in nums[]
is used. Each time when we get a curSum = sum/k
, we will start from position 0 in nums[]
to look up the elements that are not used yet and find another curSum = sum/k
.
An corner case is when sum = 0
, so we could use curNum
to record the number of elements in the current subset. Only ifcur_sum = sum/k && cur_num >0
, we can start another look up process.
Code
class Solution {
public boolean canPartitionKSubsets(int[] nums, int k) {
int sum = 0;
for (int n : nums){
sum += n;
}
if (sum % k != 0){
return false;
}
int[] visited = new int[nums.length];
return canPartitionHelper(nums, visited, k, 0, 0, 0, sum/k);
}
private boolean canPartitionHelper(int[] nums, int[] visited, int k, int startIndex, int curSum, int curNum, int target){
if (k == 1){
return true;
}
if (curSum == target && curNum > 0){
return canPartitionHelper(nums, visited, k - 1, 0, 0, 0, target);
}
for (int i = startIndex; i < nums.length; i++){
if (visited[i] == 0){
visited[i] = 1;
if (canPartitionHelper(nums, visited, k, i + 1, curSum + nums[i], curNum++, target)){
return true;
}
visited[i] = 0;
}
}
return false;
}
}
Time Complexity: O(n^2)
Space Complexity: O(n)