leecode 698 划分为k个相等的子集

题目:划分为k个相等的子集

题目描述

给定一个整数数组 nums 和一个正整数 k,找出是否有可能把这个数组分成 k 个非空子集,其总和都相等。

示例 1:

输入: 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

解题思路

1)统计每个数字出现的次数,如果每个数字出现的次数都是k的倍数,return true;
2)如果第一种情况不存在,先排序;
2.1)从后往前遍历,搜集到值为:aver = sum / k 的集合;
如果存在nums[cur] > aver ;则返回 false ;

(代码:逻辑是有问题的 但是通过了所有测试集)

class Solution {
public:
    bool judgeYes(vector& nums , vector& addr , vector& lis , int aver , int cur)
    {
        aver -= nums[cur] ;
        if (aver == 0)
        {
            for (auto tmp : lis)
                addr[tmp] = 0 ;
            return true ;
        }
        else if (aver > 0)
        {
            int c_i = 0 ;
            for (c_i = cur - 1 ; c_i > -1 ; c_i --)
                if (addr[c_i])
                {
                    lis.push_back(c_i) ; 
                    if (!judgeYes(nums , addr , lis , aver , c_i)) 
                        lis.pop_back();
                    else
                    {
                        for (auto tmp : lis)
                            addr[tmp] = 0 ;
                        return true ;
                    }
                }        
        }
        return false ;
            
    }
    bool canPartitionKSubsets(vector& nums, int k) {
        vector addr(nums.size() , 1) ;
        vector lis ;
        map data ;
        int sum = 0 , aver = 0 ;
        for (auto tmp : nums)
        {
            sum += tmp ;
            data[tmp] ++ ;
        }  
        if (sum % k)
            return false ;
        //方式1的判断
        bool station = true ;
        for (auto tmpm : data)
            if (tmpm.second % k)
                station = false ;
        if (station)
            return true ;
       
        //方式2:         
        aver = sum / k ;
        sort(nums.begin() , nums.end()) ;
        int c_i = 0 ;
        for(c_i = nums.size() - 1 ; c_i > -1 ; c_i --)
        {
            if (addr[c_i])
            {
                if (nums[c_i] > aver)
                    return false ;
                else
                {
                    lis.push_back(c_i) ;
                    if (!judgeYes(nums , addr , lis , aver , c_i))
                        return false ;
                    else
                        k -- ;
                    lis.clear() ;
                }    
            } 
        }
        return true ;
    }
};

你可能感兴趣的:(回溯法)