力扣698.划分为K个相等的子集

题目:

给定一个整数数组  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 = [1,2,3,4], k = 3
输出: false

解决思路:可以用回溯法来解决这个问题。这里新学习了一个关于桶的方法,将它分成k分,就是有k个桶,每个桶的容积=数组总和/k,Arrays.fill(桶,容积)即一开始桶的容量就满了,循环每一个桶,依次往外倒nums[i],回溯后如果发现是false需要将之前往外倒的撤回,直到最后一个桶。

代码实现:代码是参考了大佬的,开始对这道题一点思路都没有,所谓中等,但是对我来说是困难模式啊!一开始我没有理解这句话if(i>0&&box[i]==box[i-1]) continue;它执行后,后面的程序还能不能进行?因为最开始所有的桶的容积是一样的,岂不是box[i]永远都等于box[i-1],后来才看到i的初值是0,最开始是判断box[0]==box[-1],所以后面的代码是执行了的。(应该是这样吧......)

class Solution {
    int []box;//定义盒子,之所以在这里定义,后面两个方法都需要
    public boolean canPartitionKSubsets(int[] nums, int k) {
      if(k==1)
      return true;//特殊情况
      int sum=0;
      for(int i=0;i0&&box[i]==box[i-1]) continue;//没有这个条件,判定超时,我的理解:在这层桶中,如果当前桶的容量和前一个桶是一样的,前面的没有成功,后面的也自然不用再进行回溯了。
            if(len>=0&&box[i]==num[len]||box[i]-num[len]>=num[0]){//倒出的数刚好等于剩余的容积,或是桶内倒出的数>=数组的最小值
                box[i]=box[i]-num[len];
                if(dfs(kk,num,len-1)) return true;
                box[i]=box[i]+num[len];
            }
            
        }
        return false;
    }
}

你可能感兴趣的:(力扣刷题,leetcode,数据结构,java)