力扣练习——32 划分为k个相等的子集

1.问题描述

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

 

示例 1:

输入: nums = [4, 3, 2, 3, 5, 2, 1], k = 4

输出: True

说明: 有可能将其分成 4 个子集(5),(1,4),(2,3),(2,3)等于总和。

2.输入说明

首先输入nums数组的长度n,

然后输入n个整数,以空格分隔。

最后输入k。

1 <= k <= n <= 16

0 < nums[i] < 10000

3.输出说明

输出true或false

4.范例

输入

7
4 3 2 3 5 2 1
4

输出

true

5.代码

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<set>
#include<stack>
using namespace std;

bool backtracking(vector<int>nums, vector<int>edges, int len, int index)
{
    if (index == nums.size())
        return true;                                          
                                                           
    for (int i = 0; i < edges.size(); i++)
    {
        if (nums[index] + edges[i] > len)
            continue;
        if (i > 0 && edges[i] == edges[i - 1])
            continue;

        edges[i] += nums[index];

        if (backtracking(nums, edges, len, index + 1))
            return true;

        edges[i] -= nums[index];//回溯
    }
    return false;
}


bool canPartitionKSubsets(vector<int>& nums, int k)
{
    //1.总长度小于k
    if (nums.size() < k)
        return false;
    //2.计算总长度len  ,len 必须是k的整数倍
    int len = 0;
    for (int num : nums)
        len += num;
    if (len%k != 0)
        return false;
    //3.
    int single_length = len / k;//计算单个区间的长度
    vector<int>edges(k);
    sort(nums.begin(), nums.end(), greater<int>());//从大到小排序
    
    //4.回溯
    return backtracking(nums, edges, single_length, 0);


    
}
 
int main()

{
    vector<int>nums;
    int n, k,temp;
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> temp;
        nums.push_back(temp);
    }
    cin >> k;
    bool res = canPartitionKSubsets(nums, k);
    cout << (res ? "true" : "false") << endl;
    return 0;

}

 

posted @ 2022-07-20 20:13  努力奋斗的小企鹅  阅读(109)  评论(0)    收藏  举报