0% completed
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
n
to store the length ofnums
.
- Define
-
Splitting the Array:
- Split the input array
nums
into two halves:left
will contain the firstn/2
elements ofnums
.right
will contain the remaining elements ofnums
.
- Split the input array
-
Generating Subset Sums for
left
:- Initialize an empty list
leftSums
to store the sums of all possible subsets ofleft
. - Calculate the total number of subsets for
left
. Sinceleft
hasn/2
elements, there are 2<sup>(n/2)</sup> possible subsets. - Iterate through all possible subsets using a bitmask approach:
- For each possible subset, represented by an integer
i
ranging from0
to 2<sup>(n/2)</sup> - 1, do the following:- Initialize a variable
sum
to0
to store the sum of the current subset. - For each bit
j
in the binary representation ofi
:- If the
j
-th bit ofi
is set (i.e.,i & (1 << j) != 0
), include thej
-th element ofleft
in the subset and add it tosum
.
- If the
- After processing all bits, add the calculated
sum
toleftSums
.
- Initialize a variable
- For each possible subset, represented by an integer
- The list
leftSums
now contains the sums of all possible subsets of theleft
half of the array.
- Initialize an empty list
-
Generating Subset Sums for
right
:- Initialize an empty list
rightSums
to store the sums. - Repeat the same process as in step 3 for
right
and store the sums inrightSums
.
- Initialize an empty list
-
Sorting
rightSums
:- Sort the list
rightSums
in 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
count
to0
to keep track of the number of valid subsets whose sum equalsx
. - For each sum
leftSum
inleftSums
, do the following:- Calculate the complementary sum needed to reach
x
by subtractingleftSum
fromx
(i.e.,complement = x - leftSum
). - Use binary search on the sorted list
rightSums
to find how many timescomplement
appears inrightSums
. This gives the number of valid subsets inright
that, 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
:rightSums
is 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
5
inrightSums
, which is1
. - Increment
count
by 1. (count = 1
)
- For
leftSum = 1
:complement = 5 - 1 = 4
- Use binary search to find occurrences of
4
inrightSums
, which is1
. - Increment
count
by 1. (count = 2
)
- For
leftSum = 2
:complement = 5 - 2 = 3
- Use binary search to find occurrences of
3
inrightSums
, which is1
. - Increment
count
by 1. (count = 3
)
- For
leftSum = 3
:complement = 5 - 3 = 2
- Use binary search to find occurrences of
2
inrightSums
, 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
Complexity Analysis
-
Generating Subset Sums:
- For an array of length
n
, we split it into two halves. Each half containsn/2
elements. - For each half, the number of possible subsets is 2<sup>(n/2)</sup>. Generating all subset sums for each half requires O(2<sup>(n/2)</sup> * (n/2)) time.
- For an array of length
-
Sorting:
- Sorting the
rightSums
list takes O(2<sup>(n/2)</sup> * log(2<sup>(n/2)</sup>)) = O(2<sup>(n/2)</sup> * (n/2)) time.
- Sorting the
-
Binary Search:
- For each sum in
leftSums
, we perform a binary search onrightSums
. Since there are 2<sup>(n/2)</sup> sums inleftSums
and each binary search takes O(log(2<sup>(n/2)</sup>)) = O(n/2) time, this part requires O(2<sup>(n/2)</sup>* (n/2)) time.
- For each sum in
The overall time complexity of this approach is O(2<sup>(n/2)</sup> * (n/2)).
Space Complexity:
The space complexity is dominated by the storage of subset sums, which takes 2<sup>(n/2)</sup> space for each half. Thus, the space complexity is 2<sup>(n/2)</sup>.
.....
.....
.....
Table of Contents
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible
Contents are not accessible