Count Subsets with Sum K
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ nums.length ≤ 20 - ◆
0 ≤ nums[i] ≤ 100 - ◆
0 ≤ k ≤ 1000
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteEvery number is either left out of the subset or included in it, and both choices need to be explored since either could be part of a valid combination. Unlike a yes/no search, the recursion can't stop early the moment the remaining amount hits zero — a later number with value zero, for instance, could still be freely included or excluded without changing the sum, and each of those choices is a distinct subset that must be counted. So the check for a valid subset only happens once every number has been decided on: if the amount still needed is exactly zero at that point, this particular combination of choices counts as one way. Adding up the ways from the "exclude" and "include" branches at every step counts every valid combination exactly once.
O(2^n)O(n)1class Solution {
2 private int[] nums;
3
4 public int countSubsetsWithSumK(int[] nums, int k) {
5 this.nums = nums;
6 return solve(0, k);
7 }
8
9 private int solve(int i, int remaining) {
10 if (i == nums.length) return remaining == 0 ? 1 : 0;
11 if (remaining < 0) return 0;
12 return solve(i + 1, remaining) + solve(i + 1, remaining - nums[i]);
13 }
14}Optimal — Bottom-Up 1D DP
OptimalTrack, for every amount from 0 up to k, how many subsets of the numbers seen so far sum to it exactly — a running count array indexed by amount. Amount 0 starts with exactly one way (the empty subset), and each number extends every amount that was already reachable before it by that number's value, adding that many new ways to the amount now reachable through it. Sweeping each number's inner update from k down to the number's own value guarantees the counts being read still reflect the state from before this number was considered, so each number contributes to each subset at most once. After every number has been swept through, the entry at k holds the total count.
O(n × k)O(k)1class Solution {
2 public int countSubsetsWithSumK(int[] nums, int k) {
3 int[] dp = new int[k + 1];
4 dp[0] = 1;
5 for (int num : nums) {
6 for (int s = k; s >= num; s--) {
7 dp[s] += dp[s - num];
8 }
9 }
10 return dp[k];
11 }
12}