LeetCode698 划分为k个相等的子集

主要用到了深度优先的搜索思想。先将题意进行转化,k个相等的子集也就是说这k个子集的和为sum,且每个子集的和为sum/k。

题目和之前的LeetCode416 分割等和子集的思想一致,也可以转换成背包问题,包的容量为sum/k。不过这次不是只找到一组数来装这一个包,而是找到多个包,这种解法可以找到正确答案,但是代码会很长,不推荐。直接用深度优先的思想做代码量就很简单了。代码如下:

class Solution {
public:
    bool canPartitionKSubsets(vector<int>& nums, int k) {
        if(k==1){//数组本身就是它的一个子集
          return true;  
        }
        if(k>nums.size()){  //不可能构成k个子集
            return false;
        }
        int sum=accumulate(nums.begin(),nums.end(),0);
        if(sum%k){
            return false;
        }
        int n=nums.size(),target=sum/k,curSum=0;
        vector<int> used(n,0);
        return ifSubsets(nums,0,0,target,curSum,k,used);
    }
    bool ifSubsets(vector<int>& nums, int start,int n,int target,int curSum,int k,vector<int>& used)
    {// start表示搜索的起点,n为当前已经搜索过的数字数目,curSum为当前的累加和,target,k,used和定义一致
        if(curSum>target){return false;}
        if(k==0&&n==nums.size()){return true;}
        if(curSum==target){  //已经存在一个集合
            return ifSubsets(nums,0,n,target,0,k-1,used);  //继续从第一个数字开始搜索,start变为0,当前和变为0
        }
        for(int i=start;i<nums.size();i++)
        {//curSum<target
            if(used[i]==0)//还没有使用过
            {
                used[i]=1;  //标识
                if(ifSubsets(nums,i+1,n+1,target,curSum+nums[i],k,used)){ //还是给第k个子集找值,所以k不变;要把i处的值加上,并从他的下一个位置搜索
                    return true;
                }
                used[i]=0;  //说明上述子集中没有用到i,所以恢复状态等待下次使用
            }
        }
        return false;
    }
};

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值