medium Subset Sum Equal to Target
Problem Statement
Given an array nums containing n integers, return the number of subsets having a sum equal to x.
A subset can be any combination of numbers from the array, including an empty subset. However, you need to consider all possible combinations to determine the exact number of subsets with a sum equal to x.
Examples
Example 1:
- Input: nums =
[1, 2, 3, 4, 5], x =5 - Expected Output:
3 - Explanation: The subsets that sum to 5 are
[5],[1, 4], and[2, 3].
Example 2:
- Input: nums =
[2, 4, 6, 10], x =16 - Expected Output:
2 - Explanation: The subsets that sum to 16 are
[6, 10]and[2, 4, 10].
Example 3:
- Input: nums =
[7, -3, 2, 5, 1], x =9 - Expected Output:
2 - Explanation: The subsets that sum to 9 are
[7, 2]and[-3, 7, 5].
Try it yourself
Try solving this question here:
✅ Solution Subset Sum Equal to Target
Problem Statement
Given an array nums containing n integers, return the number of subsets having a sum equal to x.
A subset can be any combination of numbers from the array, including an empty subset. However, you need to consider all possible combinations to determine the exact number of subsets with a sum equal to x.
Examples
Example 1:
- Input: nums =
[1, 2, 3, 4, 5], x =5 - Expected Output:
3 - Explanation: The subsets that sum to 5 are
[5],[1, 4], and[2, 3].
Example 2:
- Input: nums =
[2, 4, 6, 10], x =16 - Expected Output:
2 - Explanation: The subsets that sum to 16 are
[6, 10]and[2, 4, 10].
Example 3:
- Input: nums =
[7, -3, 2, 5, 1], x =9 - Expected Output:
2 - Explanation: The subsets that sum to 9 are
[7, 2]and[-3, 7, 5].
Solution
To solve the "Subset sum equal to x" problem efficiently, we use the "Meet in the Middle" approach, which reduces the problem size by splitting the array into two halves. The key idea is to generate all possible subset sums for each half of the array. This allows us to handle each half independently, making the problem more manageable. By doing so, we turn a potentially large problem into two smaller problems, each with a reduced number of elements. This significantly cuts down the number of subsets we need to consider.
After generating the subset sums for both halves, we sort the sums from the second half. This sorting step is crucial because it enables us to use binary search to quickly find complementary sums. For each sum in the first half, we calculate the required complementary sum that, when added together, equals the target x. We then use binary search to efficiently count how many times this complementary sum appears in the sorted list from the second half. This method is effective because it leverages the power of sorting and binary search to reduce the time complexity, making it more feasible to solve the problem even for larger inputs.
Step-by-Step Algorithm
-
Initialization:
- Define
nto store the length ofnums.
- Define
-
Splitting the Array:
- Split the input array
numsinto two halves:leftwill contain the firstn/2elements ofnums.rightwill contain the remaining elements ofnums.
- Split the input array
-
Generating Subset Sums for
left:- Initialize an empty list
leftSumsto store the sums of all possible subsets ofleft. - Calculate the total number of subsets for
left. Sincelefthasn/2elements, there are 2(n/2) possible subsets. - Iterate through all possible subsets using a bitmask approach:
- For each possible subset, represented by an integer
iranging from0to 2(n/2) - 1, do the following:- Initialize a variable
sumto0to store the sum of the current subset. - For each bit
jin the binary representation ofi:- If the
j-th bit ofiis set (i.e.,i & (1 << j) != 0), include thej-th element ofleftin the subset and add it tosum.
- If the
- After processing all bits, add the calculated
sumtoleftSums.
- Initialize a variable
- For each possible subset, represented by an integer
- The list
leftSumsnow contains the sums of all possible subsets of thelefthalf of the array.
- Initialize an empty list
-
Generating Subset Sums for
right:- Initialize an empty list
rightSumsto store the sums. - Repeat the same process as in step 3 for
rightand store the sums inrightSums.
- Initialize an empty list
-
Sorting
rightSums:- Sort the list
rightSumsin non-decreasing order. Sorting is necessary to enable efficient binary search operations in the next step.
- Sort the list
-
Counting Valid Subsets:
- Initialize a variable
countto0to keep track of the number of valid subsets whose sum equalsx. - For each sum
leftSuminleftSums, do the following:- Calculate the complementary sum needed to reach
xby subtractingleftSumfromx(i.e.,complement = x - leftSum). - Use binary search on the sorted list
rightSumsto find how many timescomplementappears inrightSums. This gives the number of valid subsets inrightthat, when combined with the subset fromleft, will sum tox. - Add this count to the total count.
- Calculate the complementary sum needed to reach
- Initialize a variable
-
Output:
- Return the value of
count, which represents the total number of subsets across both halves that sum tox.
- Return the value of
Algorithm Walkthrough
Let's go through the algorithm step by step using the provided example:
-
Input:
- Array
nums = [1, 2, 3, 4, 5] - Target
x = 5 - Length
n = 5
- Array
-
Splitting the Array:
left = [1, 2]right = [3, 4, 5]
-
Generating Subset Sums for
left:- Subsets of
left = [1, 2]are:- Subset
{}: Sum = 0 - Subset
{1}: Sum = 1 - Subset
{2}: Sum = 2 - Subset
{1, 2}: Sum = 3
- Subset
leftSums = [0, 1, 2, 3]
- Subsets of
-
Generating Subset Sums for
right:- Subsets of
right = [3, 4, 5]are:- Subset
{}: Sum = 0 - Subset
{3}: Sum = 3 - Subset
{4}: Sum = 4 - Subset
{5}: Sum = 5 - Subset
{3, 4}: Sum = 7 - Subset
{3, 5}: Sum = 8 - Subset
{4, 5}: Sum = 9 - Subset
{3, 4, 5}: Sum = 12
- Subset
rightSums = [0, 3, 4, 5, 7, 8, 9, 12]
- Subsets of
-
Sorting
rightSums:rightSumsis already sorted, so no changes are needed.
-
Counting Valid Subsets:
- Initialize
count = 0. - For
leftSum = 0:complement = 5 - 0 = 5- Use binary search to find occurrences of
5inrightSums, which is1. - Increment
countby 1. (count = 1)
- For
leftSum = 1:complement = 5 - 1 = 4- Use binary search to find occurrences of
4inrightSums, which is1. - Increment
countby 1. (count = 2)
- For
leftSum = 2:complement = 5 - 2 = 3- Use binary search to find occurrences of
3inrightSums, which is1. - Increment
countby 1. (count = 3)
- For
leftSum = 3:complement = 5 - 3 = 2- Use binary search to find occurrences of
2inrightSums, which is0. - No change to
count. (count = 3)
- Initialize
-
Output:
- The final result is
count = 3, which matches the expected output.
- The final result is
Code
import java.util.*;
public class Solution {
// Method to find the number of subsets that sum up to the target x using the meet in the middle approach
public int countSubsets(int[] nums, int x) {
int n = nums.length;
// Split the array into two halves
int[] left = Arrays.copyOfRange(nums, 0, n / 2);
int[] right = Arrays.copyOfRange(nums, n / 2, n);
// Generate all possible subset sums for each half
List<Integer> leftSums = generateSubsetSums(left);
List<Integer> rightSums = generateSubsetSums(right);
// Sort the right sums to use binary search
Collections.sort(rightSums);
int count = 0;
// For each sum in the leftSums list, find the complementary sum in rightSums that sums up to x
for (int leftSum : leftSums) {
int complement = x - leftSum;
count += countOccurrences(rightSums, complement);
}
return count;
}
// Helper method to generate all possible subset sums for a given array
private List<Integer> generateSubsetSums(int[] nums) {
List<Integer> sums = new ArrayList<>();
int n = nums.length;
// There are 2^n possible subsets
for (int i = 0; i < (1 << n); i++) {
int sum = 0;
for (int j = 0; j < n; j++) {
// Check if jth element is included in the subset
if ((i & (1 << j)) != 0) {
sum += nums[j];
}
}
sums.add(sum);
}
return sums;
}
// Helper method to count occurrences of a target value in a sorted list using binary search
private int countOccurrences(List<Integer> list, int target) {
// Find the first occurrence of the target using binary search
int leftIndex = Collections.binarySearch(list, target);
if (leftIndex < 0) {
return 0; // Target not found
}
// Find the range of elements equal to target
int count = 0;
int index = leftIndex;
// Count occurrences to the left
while (index >= 0 && list.get(index) == target) {
count++;
index--;
}
// Count occurrences to the right
index = leftIndex + 1;
while (index < list.size() && list.get(index) == target) {
count++;
index++;
}
return count;
}
// Main method to test the function with different examples
public static void main(String[] args) {
Solution solution = new Solution();
// Test case 1
int[] nums2 = {1, 2, 3, 4, 5};
int x2 = 5;
System.out.println("Number of subsets that sum to " + x2 + ": " + solution.countSubsets(nums2, x2));
// Expected output: 3
// Test case 2
int[] nums1 = {2, 4, 6, 10};
int x1 = 16;
System.out.println("Number of subsets that sum to " + x1 + ": " + solution.countSubsets(nums1, x1));
// Expected output: 2
// Test case 3
int[] nums3 = {7, -3, 2, 5, 1};
int x3 = 9;
System.out.println("Number of subsets that sum to " + x3 + ": " + solution.countSubsets(nums3, x3));
// Expected output: 2
}
}
Complexity Analysis
-
Generating Subset Sums:
- For an array of length
n, we split it into two halves. Each half containsn/2elements. - For each half, the number of possible subsets is 2(n/2). Generating all subset sums for each half requires O(2(n/2) * (n/2)) time.
- For an array of length
-
Sorting:
- Sorting the
rightSumslist takes O(2(n/2) * log(2(n/2))) = O(2(n/2) * (n/2)) time.
- Sorting the
-
Binary Search:
- For each sum in
leftSums, we perform a binary search onrightSums. Since there are 2(n/2) sums inleftSumsand each binary search takes O(log(2(n/2))) = O(n/2) time, this part requires O(2(n/2)* (n/2)) time.
- For each sum in
The overall time complexity of this approach is O(2(n/2) * (n/2)).
Space Complexity:
The space complexity is dominated by the storage of subset sums, which takes 2(n/2) space for each half. Thus, the space complexity is 2(n/2).
🤖 Don't fully get this? Learn it with Claude
Stuck on Subset Sum Equal to Target? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.
Progressively stronger hints — you still solve it.
I'm working on the problem **Subset Sum Equal to Target** (DSA). Give me a HINT LADDER: start with the tiniest nudge, then wait. Only reveal the next, stronger hint when I ask. Do NOT show the full solution unless I type 'show solution'. Keep me doing the thinking. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
See the technique, not just code.
Explain the optimal approach to **Subset Sum Equal to Target** with a VISUAL walkthrough: trace it on a small concrete example using ASCII art / a step-by-step diagram, narrate what changes each step, then give time & space complexity with a one-line derivation. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Catch bugs, edge cases, sub-optimality.
I'll paste my solution to **Subset Sum Equal to Target**. Review it for correctness, missed edge cases, and time/space complexity, then coach me toward the optimal — don't just rewrite it. Ask me to paste my code now. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
Lock in recognition with look-alikes.
Give me 2 problems that use the SAME underlying pattern as **Subset Sum Equal to Target**. For each, let me attempt first, then review my answer and name the trigger signal that reveals the pattern. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.