0% completed
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
.
Example 1:
[1, 2, 3, 4, 5]
, x = 5
3
[5]
, [1, 4]
, and [2, 3]
.Example 2:
[2, 4, 6, 10]
, x = 16
2
[6, 10]
and [2, 4, 10]
.Example 3:
[7, -3, 2, 5, 1]
, x = 9
2
[7, 2]
and [-3, 7, 5]
.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.
Initialization:
n
to store the length of nums
.Splitting the Array:
nums
into two halves:
left
will contain the first n/2
elements of nums
.right
will contain the remaining elements of nums
.Generating Subset Sums for left
:
leftSums
to store the sums of all possible subsets of left
.left
. Since left
has n/2
elements, there are 2<sup>(n/2)</sup> possible subsets.i
ranging from 0
to 2<sup>(n/2)</sup> - 1, do the following:
sum
to 0
to store the sum of the current subset.j
in the binary representation of i
:
j
-th bit of i
is set (i.e., i & (1 << j) != 0
), include the j
-th element of left
in the subset and add it to sum
.sum
to leftSums
.leftSums
now contains the sums of all possible subsets of the left
half of the array.Generating Subset Sums for right
:
rightSums
to store the sums.right
and store the sums in rightSums
.Sorting rightSums
:
rightSums
in non-decreasing order. Sorting is necessary to enable efficient binary search operations in the next step.Counting Valid Subsets:
count
to 0
to keep track of the number of valid subsets whose sum equals x
.leftSum
in leftSums
, do the following:
x
by subtracting leftSum
from x
(i.e., complement = x - leftSum
).rightSums
to find how many times complement
appears in rightSums
. This gives the number of valid subsets in right
that, when combined with the subset from left
, will sum to x
.Output:
count
, which represents the total number of subsets across both halves that sum to x
.Let's go through the algorithm step by step using the provided example:
Input:
nums = [1, 2, 3, 4, 5]
x = 5
n = 5
Splitting the Array:
left = [1, 2]
right = [3, 4, 5]
Generating Subset Sums for left
:
left = [1, 2]
are:
{}
: Sum = 0{1}
: Sum = 1{2}
: Sum = 2{1, 2}
: Sum = 3leftSums = [0, 1, 2, 3]
Generating Subset Sums for right
:
right = [3, 4, 5]
are:
{}
: Sum = 0{3}
: Sum = 3{4}
: Sum = 4{5}
: Sum = 5{3, 4}
: Sum = 7{3, 5}
: Sum = 8{4, 5}
: Sum = 9{3, 4, 5}
: Sum = 12rightSums = [0, 3, 4, 5, 7, 8, 9, 12]
Sorting rightSums
:
rightSums
is already sorted, so no changes are needed.Counting Valid Subsets:
count = 0
.leftSum = 0
:
complement = 5 - 0 = 5
5
in rightSums
, which is 1
.count
by 1. (count = 1
)leftSum = 1
:
complement = 5 - 1 = 4
4
in rightSums
, which is 1
.count
by 1. (count = 2
)leftSum = 2
:
complement = 5 - 2 = 3
3
in rightSums
, which is 1
.count
by 1. (count = 3
)leftSum = 3
:
complement = 5 - 3 = 2
2
in rightSums
, which is 0
.count
. (count = 3
)Output:
count = 3
, which matches the expected output.Generating Subset Sums:
n
, we split it into two halves. Each half contains n/2
elements.Sorting:
rightSums
list takes O(2<sup>(n/2)</sup> * log(2<sup>(n/2)</sup>)) = O(2<sup>(n/2)</sup> * (n/2)) time.Binary Search:
leftSums
, we perform a binary search on rightSums
. Since there are 2<sup>(n/2)</sup> sums in leftSums
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.The overall time complexity of this approach is O(2<sup>(n/2)</sup> * (n/2)).
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>.
.....
.....
.....