Dividing an array into K subsets such that sum of all subsets is same using bitmasksDP
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Dividing an array into `K` subsets such that the sum of all subsets is the same is a fascinating problem in computer science and combinatorial mathematics. This problem belongs to the class of partition problems and can be efficiently tackled using dynamic programming (DP) combined with bitmask techniques. This approach leverages the power of bit manipulation to represent subsets and systematically explore potential solutions, making it a powerful tool for solving complex optimization problems.
Problem Statement
Given an array of integers `arr` and an integer `K`, you are tasked with partitioning `arr` into `K` subsets such that the sum of each subset is identical. If partitioning is feasible, the integer division of the total array sum by `K` should yield the subset sum.
Solution Approach
Key Idea: Use bitmasks to represent subsets of `arr` and employ dynamic programming to track achievable sums.
Prerequisites
- Subset Representation with Bitmasks: A bitmask represents the selection of elements in an array. For instance, a bitmask `101` (in binary) indicates selecting elements at indices 0 and 2 in an array of size 3.
- Dynamic Programming Table: A DP table indexed by bitmask states can store whether a particular subset sum is achievable.
Steps to Solve the Problem
- Calculate Target Subset Sum:
- Calculate the `total_sum` of `arr`.
- If `total_sum` modulo `K` is not zero, return `false` because it is impossible to partition `arr` into equal sum subsets.
- Set `target` as `total_sum / K`.
- Initialize DP Structures:
- Define a DP array `dp` where `dp[mask]` is `True` if a selection of elements represented by `mask` can form a subset sum of `target`.
- Start with `dp[0] = True` which signifies that an empty subset has a sum of 0.
- Define an auxiliary array `current_sum` to track current subset sums corresponding to each bitmask.
- Iterate Over Subset Selections:
- For each bitmask `mask`, check if `dp[mask]` is true—indicating it reaches a valid subset configuration.
- Attempt to add each unchosen element from `arr` into the current subset. For a selected element not yet present in the subset (tracked via the bitmask), compute the new mask.
- Update the `dp` and `current_sum` arrays accordingly.
- Check Solution:
- The solution exists if `dp[(1 << n) - 1]` is true, where `(1 << n) - 1` is a bitmask with all elements selected.
Complexity Analysis
- Time Complexity:
- `2^N` for iterating through all possible subsets.
- `N` for attempting to add each element to each subset.
- Space Complexity:
- Space is required for the boolean DP table and current sum array for each bitmask.
Example
Consider `arr = [4, 3, 2, 3, 5, 2, 1]` and `K = 4`:
- Check if the `total_sum` of the array is divisible by `K`:
- `total_sum = 20`; `20 / 4 = 5`. Valid configuration since divisible.
- Initialize `dp` and check subsets:
- `dp[0] = True`, `current_sum[0] = 0`.
- Check combinations of numbers using bitmasks to achieve a subset sum of 5.
- Continue until all 7 elements are utilized (`mask = 1111111`).
Conclusion
The bitmask plus DP approach provides an efficient method for solving the problem of dividing an array into `K` subsets with equal sums by systematically evaluating every subset. This method takes advantage of binary representation for sets and dynamic storage of achievable states, resulting in a robust solution for relatively small arrays due to its exponential complexity.
Summary Table
| Aspect | Description |
| Problem Statement | Partition array into K subsets with equal sums |
| Target Condition | total\_sum % K == 0; Subset sum = total\_sum / K |
| Approach | Bitmasking + Dynamic Programming |
| Time Complexity | |
| Space Complexity | |
| Example | arr = \[4, 3, 2, 3, 5, 2, 1], K = 4, subsets possible |
| Feasibility Check | total\_sum / K should yield integer subset sum |
This approach effectively balances between complexity and computational capabilities by utilizing dynamic programmatic techniques intertwined with bit-level operations.

