698. 划分为k个相等的子集

Java:回溯
class Solution {
    boolean[] used;
    int target;
    private boolean backtracking(int[] nums, int k, int sum, int start) {
        if (k == 0) {
            return true;  // 找到:立即中断栈!并返回值
        }
        if (sum == target) { // 构建下一个集合, return相当于把上一个dfs堆栈给掐掉
            return backtracking(nums, k-1, 0, 0); 
        }
        for (int i = start; i < nums.length; i++) {  // 逐渐过滤已使用的数字,用剩下的数字重新回溯看能否构建
            if (!used[i] && sum + nums[i] <= target) {
                used[i] = true;
                if (backtracking(nums, k, sum + nums[i], i + 1)) {
                    return true;
                }
                used[i] = false;
            }
        }
        return false;
    }
    
    public boolean canPartitionKSubsets(int[] nums, int k) {
        // 注意nums[i] > 0
        int sum = 0, maxNum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            maxNum = Math.max(maxNum, nums[i]);
        }
        if (sum % k != 0 || maxNum > sum/k) {
             return false;
        }
        used = new boolean[nums.length];
        target = sum / k;
        return backtracking(nums, k, 0, 0);
    }
}



















