Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
C / C++ Program for Subset Sum (Backtracking)
Backtracking is a technique to solve dynamic programming problems. It works by going step by step and rejects those paths that do not lead to a solution and trackback (moves back) to the previous position.
In the subset sum problem, we have to find the subset of a set such that the elements of this subset sum up to a given number K. All the elements of the set are positive and unique (no duplicate elements are present).
Syntax
void subset_sum(int s[], int t[], int s_size, int t_size, int sum, int index, int target_sum);
Algorithm
The backtracking algorithm for subset sum works as follows −
- Start with an empty subset and sum = 0
- For each element, we have two choices: include it or exclude it
- If including the element makes sum equal to target, print the subset
- If sum exceeds target, backtrack
- Continue until all possibilities are explored
Example
Let's implement the subset sum problem using backtracking in C −
#include <stdio.h>
#include <stdlib.h>
static int total_nodes;
void printValues(int A[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", A[i]);
}
printf("\n");
}
void subset_sum(int s[], int t[], int s_size, int t_size, int sum, int ite, int const target_sum) {
total_nodes++;
if (target_sum == sum) {
printValues(t, t_size);
/* Backtrack to find more solutions */
if (ite < s_size) {
subset_sum(s, t, s_size, t_size - 1, sum - s[ite-1], ite, target_sum);
}
return;
}
/* Try including each remaining element */
for (int i = ite; i < s_size; i++) {
/* Pruning: if current sum + current element exceeds target, skip */
if (sum + s[i] <= target_sum) {
t[t_size] = s[i];
subset_sum(s, t, s_size, t_size + 1, sum + s[i], i + 1, target_sum);
}
}
}
void generateSubsets(int s[], int size, int target_sum) {
int* tuplet_vector = (int*)malloc(size * sizeof(int));
if (tuplet_vector == NULL) {
printf("Memory allocation failed\n");
return;
}
printf("Subsets with sum %d:\n", target_sum);
subset_sum(s, tuplet_vector, size, 0, 0, 0, target_sum);
free(tuplet_vector);
}
int main() {
int set[] = {5, 6, 12, 54, 2, 20, 15};
int size = sizeof(set) / sizeof(set[0]);
int target = 25;
printf("The set is: ");
printValues(set, size);
generateSubsets(set, size, target);
printf("Total nodes generated: %d\n", total_nodes);
return 0;
}
The set is: 5 6 12 54 2 20 15 Subsets with sum 25: 5 20 5 6 12 2 Total nodes generated: 64
How It Works
The algorithm explores all possible combinations by −
- Inclusion: Add current element to subset and recurse
- Exclusion: Skip current element and move to next
- Pruning: Skip branches where sum already exceeds target
- Backtracking: Remove element when returning from recursion
Time Complexity
The time complexity is O(2^n) in worst case where n is the number of elements, as we explore all possible subsets. The space complexity is O(n) for the recursion stack.
Conclusion
The subset sum problem using backtracking efficiently finds all valid subsets by exploring possibilities systematically. Pruning optimization reduces unnecessary computations by avoiding branches that exceed the target sum.
