zoukankan      html  css  js  c++  java
  • 698. Partition to K Equal Sum Subsets

    Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into k non-empty subsets whose sums are all equal.

    Example 1:

    Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
    Output: True
    Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums.

    Note:

    • 1 <= k <= len(nums) <= 16.
    • 0 < nums[i] < 10000.

    Approach #1: DFS + Backtracking. [C++]

    class Solution {
    public:
        bool canPartitionKSubsets(vector<int>& nums, int k) {
            int len = nums.size();
            if (k == 1) return true;
            if (len < k) return false;  
            
            int sum = 0;
            for (int num : nums)
                sum += num;
            if (sum % k != 0) return false;
            
            int avg = sum / k;
            vector<int> token(len+5, 0), subsets(k+5, 0);
            subsets[0] = nums[len-1];
            token[len-1] = 1;
            return solve(nums, token, subsets, avg, k, len, 0, len-1);
        }
        
    private:
        bool solve(vector<int>& nums, vector<int>& token, vector<int>& subsets,
                   const int& avg, const int& k, const int& len, int curIdx, int limitIdx) {
            if (subsets[curIdx] == avg) {
                if (curIdx == k-2) return true;
                return solve(nums, token, subsets, avg, k, len, curIdx+1, len-1);
            }
            
            for (int i = limitIdx; i >= 0; --i) {
                if (token[i] == 1) continue;
                int tmp = subsets[curIdx] + nums[i];
                
                if (tmp <= avg) {
                    subsets[curIdx] += nums[i];
                    token[i] = 1;
                    bool nxt = solve(nums, token, subsets, avg, k, len, curIdx, i-1);
                    subsets[curIdx] -= nums[i];
                    token[i] = 0;
                    if (nxt) return true;
                }
            }
            
            return false;
        }
    };
    

      

    Analysis:

    We can solve this problem recursively, we keep an array for sum of each partition and a array to check whether an element is already taken into some partition or not.

    First we need to check some base cases:

    If K is 1, then we already have our answer, complete array is only sbset with same sum.

    If N < K, then it is not possible to divide array into subsets with equal sum, because we can't divide the array into more than N parts.

    If sum of array is not divisible by K. then it is not possible to divide the array. We will proceed only if k divides sum. Our goal reduces to divide array into K parts where sum of each part should be array_sum / k

    In above code  a recursive method is written which tries to add array element into some subset. If sum of this subset reaches required sum, we iterator for next part recursively, otherwise we backtrack for different set of elements. If number of subsets whose sum reaches the required sum is (K-1), we flag that it is possible to partition array nto K parts with equal sum, because remaining elements already have a sum equal to required sum.

    Reference:

    https://www.geeksforgeeks.org/partition-set-k-subsets-equal-sum/

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    【刷题】UOJ #274 【清华集训2016】温暖会指引我们前行
    【刷题】BZOJ 3669 [Noi2014]魔法森林
    【刷题】BZOJ 2594 [Wc2006]水管局长数据加强版
    (84)Wangdao.com第十八天_JavaScript 文档对象模型 DOM
    (84)Wangdao.com第十八天_JavaScript Promise 对象
    (83)Wangdao.com第十七天_JavaScript 定时器
    (82)Wangdao.com第十六天_JavaScript 异步操作
    (81)Wangdao.com第十六天_JavaScript 严格模式
    (80)Wangdao.com第十六天_JavaScript Object 对象的相关方法
    (79)Wangdao.com第十五天_JavaScript 对象的继承_prototype原型对象_封装_函数式编程
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10532684.html
Copyright © 2011-2022 走看看