本题并没有很难,就是很常规的排列组合,但是没有做出来。😄。可能是因为作息不好吧。
大致思路:
- 穷举所有的排列组合
- 利用类似DFS的方式进行遍历
- 两种提前结束的可能(也是本题的相对难点):
- 的时候:说明之前的都满足
- 当前的
sum
和targetSum
相等的时候:可以去找下一个可能性;同时也要注意,remaining
必须大于0
,避免出现空的集合
复杂度分析:
- 时间复杂度:非常类似穷举
- 空间复杂度:用了额外的数组,所以是
代码如下所示:
class Solution {
public boolean canPartitionKSubsets(int[] nums, int k) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % k != 0) {
return false;
}
boolean[] visited = new boolean[nums.length];
return DFS(nums, visited, 0, 0, sum / k, k, nums.length);
}
private boolean DFS(int[] nums, boolean[] visited, int start, int currentSum, int target, int k, int remaining) {
if (k == 1) {
return true;
}
if (currentSum == target && remaining > 0) {
// ensure no empty set
return DFS(nums, visited, 0, 0, target, k - 1, remaining);
}
for (int i = start; i < nums.length; ++i) {
if (!visited[i]) {
visited[i] = true;
if (DFS(nums, visited, i + 1, currentSum + nums[i], target, k, remaining - 1)) {
return true;
}
visited[i] = false;
}
}
return false;
}
}