Leetcode leetcode 698. Divide into k equal subsets

CSDN Topic Challenge Phase 2
Participation Topic: Algorithm Solution

insert image description here

Topic link and description

https://leetcode.cn/problems/partition-to-k-equal-sum-subsets/

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

Example 1:

Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4
Output: True
Explanation: It is possible to split it into 4 subsets (5), (1,4), (2,3 ), (2,3) is equal to the sum.
Example 2:

Input: nums = [1,2,3,4], k = 3
Output: false

hint:

1 <= k <= len(nums) <= 16
0 < nums[i] < 10000
The frequency of each element is in the range [1,4]

Keywords: recursion

method one:

run screenshot

insert image description here

the code

  • The array is divided into k non-empty subsets and the sum is equal. The sum can be known as: sum(nums)/k = sum of subsets m

  • If the remainder here is not 0, it means that it cannot be divided equally

  • At the same time, the elements are greater than 0, and the maximum value is greater than m, which cannot be combined

  • It is conceivable that after sorting first, the double pointers are summed, and the set is assembled to make it equal to m

  • But the left pointer needs to match the big ones as much as possible, because the small ones can be more than a few to form the average value, and the large numbers cannot be grouped, and the left pointer starts from the right pointer, so use a serial number to recursively traverse

  • At the beginning, the variable is stored in advance, and recursion is required later to avoid the trouble of passing parameters



    int[] numsField;
    int index, avg, kNum;
    
    public boolean canPartitionKSubsets(int[] nums, int k) {
    
    
        
        numsField = nums;
        kNum = k;
        int total = 0;
        // 计算总值
        for (int x : numsField) {
    
    
            total += x;
        }
        // 平均值不等显然无法凑齐
        if (total % kNum != 0) {
    
    
            return false; 
        }
        // 排序后遍历
        Arrays.sort(numsField);
        index = numsField.length; avg = total / kNum;
        return dfs(index - 1, 0, 0, new boolean[index]);
    }
    boolean dfs(int idx, int currentSum, int countK, boolean[] vis) {
    
    
        // 如果统计的k数等于预期的,完成
        if (countK == kNum) {
    
    
            return true;
        }
        // 如果当前累积已经满足平均值,接着遍历下一个数
        if (currentSum == avg) {
    
    
            return dfs(index - 1, 0, countK + 1, vis);
        }
        // 如果遍历完成,却cur不等avg
        if (idx == -1) {
    
    
            return false;
        }
        // 继续迭代,遍历查询
        for (int i = idx; i >= 0; i--) {
    
     
            // 访问过 或者 大于 显然不符合
            if (vis[i] || currentSum + numsField[i] > avg) {
    
    
                continue;
            }
            // 小于或者等于 则设为访问过
            vis[i] = true;
            // 将下一个推入,如果是符合的则返回true
            if (dfs(i - 1, currentSum + numsField[i], countK, vis)) {
    
    
                return true;
            }
            // 不符合要将恢复false , 可能存在后续的数组使用
            vis[i] = false;
            // 当前累积值如果是0 直接返回false 说明已经没有数了
            if (currentSum == 0) {
    
    
                return false; 
            }
        }
        // 最后都没有找到
        return false;
    }  

end

Welcome to communicate in the comment area, check in every day, and rush! ! !

Guess you like

Origin blog.csdn.net/qq_35530042/article/details/126950925