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)
  • 相关阅读:
    LeetCode 32. 最长有效括号(Longest Valid Parentheses)
    LeetCode 141. 环形链表(Linked List Cycle)
    LeetCode 160. 相交链表(Intersection of Two Linked Lists)
    LeetCode 112. 路径总和(Path Sum)
    LeetCode 124. 二叉树中的最大路径和(Binary Tree Maximum Path Sum)
    LightGBM新特性总结
    sql service 事务与锁
    C#泛型实例详解
    C# 中的委托和事件(详解)
    C# DateTime日期格式化
  • 原文地址:https://www.cnblogs.com/h-hkai/p/10532684.html
Copyright © 2011-2022 走看看