Partition to K Equal Sum Subsets

Medium BacktrackingRecursionArray

Problem

Given an integer array nums and an integer k, return true if nums can be split into k non-empty subsets whose sums are all equal. Every element must belong to exactly one subset.

Example 1 Input: nums = [4,3,2,3,5,2,1], k = 4 Output: true Explain: The four subsets {5}, {1,4}, {2,3}, {2,3} each sum to 5.
Example 2 Input: nums = [1,2,3,4], k = 3 Output: false Explain: The total 10 is not divisible by 3, so equal subsets are impossible.

Constraints

Approach — Backtracking

This is a Backtracking problem. The idea: build candidates one choice at a time and abandon a branch the moment it can't lead to a valid answer. Work through the reference code below line by line, then re-derive it yourself in the editor — that's how the pattern sticks.

Complexity: exponential worst case.

Solution code

Python

class Solution:
    def canPartitionKSubsets(self, nums, k):
        total = sum(nums)
        if total % k:
            return False
        target = total // k
        nums.sort(reverse=True)
        if nums[0] > target:
            return False
        used = [False] * len(nums)
        def bt(count, cur, start):
            if count == k:
                return True
            if cur == target:
                return bt(count + 1, 0, 0)
            for i in range(start, len(nums)):
                if used[i] or cur + nums[i] > target:
                    continue
                used[i] = True
                if bt(count, cur + nums[i], i + 1):
                    return True
                used[i] = False
            return False
        return bt(0, 0, 0)

Java

import java.util.Arrays;

class Solution {
    public boolean canPartitionKSubsets(int[] nums, int k) {
        int sum = 0;
        for (int x : nums) sum += x;
        if (k <= 0 || sum % k != 0) return false;
        int target = sum / k;
        Arrays.sort(nums);
        // The largest element cannot exceed a single bucket.
        if (nums[nums.length - 1] > target) return false;
        boolean[] used = new boolean[nums.length];
        return build(nums, used, nums.length - 1, 0, target, k);
    }

    // Fill one bucket at a time. cur is the running sum of the bucket
    // currently being filled; k buckets still need completing.
    private boolean build(int[] nums, boolean[] used, int idx,
                          int cur, int target, int k) {
        if (k == 1) return true;                 // last bucket auto-balances
        if (cur == target) {
            return build(nums, used, nums.length - 1, 0, target, k - 1);
        }
        for (int i = idx; i >= 0; i--) {
            if (used[i] || cur + nums[i] > target) continue;
            used[i] = true;
            if (build(nums, used, i - 1, cur + nums[i], target, k)) return true;
            used[i] = false;
            // Skip equal values — re-trying them explores the same branch.
            while (i > 0 && nums[i - 1] == nums[i]) i--;
        }
        return false;
    }
}

Practice it

Reading a solution isn't the same as being able to write it under pressure. Open this problem in the in-browser editor, hide the solution, and solve it from scratch — your code runs against real test cases instantly.

Solve Partition to K Equal Sum Subsets interactively → ← All solutions