The Subset Sum Problem is a well-known problem in computer science and a famous candidate for dynamic programming techniques. Simply put, given a set of integers and a target sum, the challenge is to decide whether there's a subset of these integers that adds up to the target. For example, consider the set {3, 34, 4, 12, 5, 2}
and a target sum of 9
. The subset {4, 5}
sums up to 9
, making it a solution to the problem.
Given a set of positive integers S
and an integer target T
, the problem can be formulated as:
S = {s1, s2, ..., sn}
and a target sum T
.S
can sum up to T
.To get started, it helps to approach the problem recursively. The idea is to take one of two paths for each element in the set:
Here's how the recursive function can be structured:
0
, return true
(an empty subset sums to 0
).false
.solve(S, n-1, T)
: Exclude the current element.solve(S, n-1, T - S[n-1])
: Include the current element if it does not exceed our target.def subset_sum(S, n, T): if T == 0: return True if n == 0: return False if S[n-1] > T: return subset_sum(S, n-1, T) return subset_sum(S, n-1, T) or subset_sum(S, n-1, T - S[n-1])
For S = {3, 34, 4, 12, 5, 2}
and T = 9
:
9
.While the recursive approach is intuitive, it has exponential time complexity due to overlapping subproblems. Therefore, a dynamic programming approach can drastically reduce this complexity to O(n*T)
by using a 2D table to store intermediate results.
The idea is to create a table dp
where dp[i][j]
is true
if a subset with sum j
can be formed using the first i
elements.
Table Initialization:
dp[0][0]
is true
(the empty set can sum to 0
).dp[i][0]
for all i
are true
(zero sum can always be obtained by selecting no elements).Filling the Table:
0
to target T
.dp
based on whether to include or exclude the current element.def subset_sum_dp(S, T): n = len(S) dp = [[False] * (T + 1) for _ in range(n + 1)] for i in range(n + 1): dp[i][0] = True # A sum of 0 is always possible for i in range(1, n + 1): for j in range(1, T + 1): if S[i-1] > j: dp[i][j] = dp[i-1][j] else: dp[i][j] = dp[i-1][j] or dp[i-1][j - S[i-1]] return dp[n][T]
For S = {3, 34, 4, 12, 5, 2}
and T = 9
, calling subset_sum_dp(S, T)
will return True
.
O(n*T)
, where n
is the number of elements in the set, and T
is the target sum.O(n*T)
for the dynamic table or can be optimized to O(T)
using 1D arrays when considering only the last row's results at a time.The Subset Sum Problem isn't just an academic curiosity; it can be seen in scenarios like:
Understanding the Subset Sum Problem thoroughly will bolster your skills in dynamic programming, providing a solid foundation for tackling more complex problems in algorithm design and analysis. Happy coding!
08/12/2024 | DSA
16/11/2024 | DSA
15/11/2024 | DSA
13/10/2024 | DSA
06/12/2024 | DSA
16/11/2024 | DSA
06/12/2024 | DSA
13/10/2024 | DSA
06/12/2024 | DSA
15/11/2024 | DSA
16/11/2024 | DSA