Leetcode 698. 划分为k个相等的子集
题目
给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。
示例:
输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
输出: True
说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。
提示:
- 1 <= k <= len(nums) <= 16
- 0 < nums[i] < 10000
题解
dfs深搜回溯
我们先计算数组所有数字的和,看是否可以整除k,不能整除则一定不能划分;否则,sum/k得到目标值,之后用dfs进行分配
我们按照第now个集合选数的方式进行dfs深搜回溯,显然选一个数要保证当前集合的元素和加上这个数后要<=目标值。
详细过程见代码
代码
vector<int> use;
bool dfs(int pos,vector<int>& nums,int now,int nowSum,int target,int k){
if(now == k) return true; //k个集合均被分配完
if(pos == nums.size()) return false;
for(int i=pos; i<nums.size(); i++){
if(use[i] == 0){
if(nowSum+nums[i] < target){ //继续从这个集合进行分配数
use[i] = 1;
if(dfs(i+1,nums,now,nowSum+nums[i],target,k)) return true;
use[i] = 0;
}else if(nowSum+nums[i] == target){ //从下个集合进行分配数
use[i] = 1;
if(dfs(0,nums,now+1,0,target,k)) return true;
use[i] = 0;
}
}
}
return false;
}
bool canPartitionKSubsets(vector<int>& nums, int k) {
int sum = 0,n = nums.size();
for(int i=0; i<n; i++)
sum += nums[i];
if(sum % k != 0) return false;
//sort(nums.begin(),nums.end(),greater<int>);
int target = sum/k;
use = vector<int>(n,0);
return dfs(0,nums,0,0,target,k);
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/partition-to-k-equal-sum-subsets
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。