Open In App

Target Sum Combinations

Last Updated : 03 Oct, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array arr[] of distinct integers and an integer target, find all unique combinations of array where the sum of chosen element is equal to target. The same element may be chosen any number of times to make target.

Examples: 

Input: arr[] = [1, 2, 3], target = 5
Output: [[1, 1, 1, 1, 1], [1, 1, 1, 2], [1, 1, 3], [1, 2, 2], [2, 3]]
Explanation: All the combination have sum of elements equals to target.

Input: arr[] = [2, 4], target = 1
Output: []
Explanation: No combination exits whose sum is equals to target

[Approach] Using Recursion and Backtracking

The idea is to explore all possible combinations of numbers that add up to the target. For each element, we reduce the target by its value and continue the process recursively. If at any point the target becomes zero, it means we have found a valid combination. On the other hand, if the target goes negative, we backtrack and discard that path. This way, recursion combined with backtracking helps us systematically generate all valid combinations without missing any possibilities.

Pseudo-code Idea

Base cases:

  • If target < 0 : not a valid combination so return back.
  • If target == 0 : valid combination so store it as an answer.

Recursive choices:
At each step, we have two options:

  • Pick the current element, reduce the target by arr[i] and call recursion with (i, target - arr[i]). Keeping the index unchanged allows us to reuse the current element until the target is either reached or exceeded.
  • Skip the current element, move to the next index and call recursion with (i+1, target).
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Function to generate all combinations
// of arr that sums to target
void makeCombination(vector<int> &arr, int remSum, vector<int> &cur, 
                     vector<vector<int>> &res, int index) {
    if (remSum == 0) {
        res.push_back(cur);
        return;
    }

    // Invalid Case: If remSum is less than 0 or if ind >= arr.size()
    if (remSum < 0 || index >= arr.size())
        return;
	
    // add the current element to the combination
    cur.push_back(arr[index]);

    // recur with the same index
    makeCombination(arr, remSum - arr[index], cur, res, index);

    // remove the current element from the combination
    cur.pop_back();
    makeCombination(arr, remSum, cur, res, index + 1);
}

// Function to find all combinations of elements
// in array arr that sum to target.
vector<vector<int>> targetSumComb(vector<int> &arr, int target) {

    // vector to store combinations
    vector<int> cur;

    // vector to valid combinations
    vector<vector<int>> res;
    makeCombination(arr, target, cur, res, 0);

    return res;
}

int main() {
    vector<int> arr = {1,2,3};
    int target = 5;

    vector<vector<int>> res = targetSumComb(arr, target);

    for (vector<int> &v : res) {
        for (int i : v) {
            cout << i << " ";
        }
        cout << endl;
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;

class GFG {

    // Function to generate all combinations
    // of arr that sums to target.
    static void makeCombination(int[] arr, int remSum, ArrayList<Integer> cur, 
                                       ArrayList<ArrayList<Integer>> res, int index) {

        if (remSum == 0) {
            res.add(new ArrayList<>(cur));
            return;
        }

        // Invalid Case: If remSum is less than 0 or if index >= arr.length
        if (remSum < 0 || index >= arr.length)
            return;
        
        // Add the current element to the combination
        cur.add(arr[index]);

        // Recur with the same index
        makeCombination(arr, remSum - arr[index], cur, res, index);

        // Remove the current element from the combination
        cur.remove(cur.size() - 1);
        makeCombination(arr, remSum, cur, res, index + 1);
    }

    // Function to find all combinations of elements
    // in array arr that sum to target.
    static ArrayList<ArrayList<Integer>> targetSumComb(int[] arr, int target) {

        // List to store combinations
        ArrayList<Integer> cur = new ArrayList<>();

        // List to store valid combinations
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        makeCombination(arr, target, cur, res, 0);

        return res;
    }

    public static void main(String[] args) {
        int[] arr = {1,2,3};
        int target = 5;

        ArrayList<ArrayList<Integer>> res = targetSumComb(arr, target);

        for (ArrayList<Integer> v : res) {
            for (int i : v) {
                System.out.print(i + " ");
            }
            System.out.println();
        }
    }
}
Python
# Function to generate all combinations
# of arr that sums to target.
def makeCombination(arr, remSum, cur, res, index):
    if remSum == 0:
        res.append(list(cur))
        return

    # Invalid Case: If remSum is less than 0 or if index >= len(arr)
    if remSum < 0 or index >= len(arr):
        return

    # Add the current element to the combination
    cur.append(arr[index])

    # Recur with the same index
    makeCombination(arr, remSum - arr[index], cur, res, index)

    # Remove the current element from the combination
    cur.pop()
    makeCombination(arr, remSum, cur, res, index + 1)

# Function to find all combinations of elements
# in array arr that sum to target.
def targetSumComb(arr, target):
    
    # List to store combinations
    cur = []

    # List to store valid combinations
    res = []
    makeCombination(arr, target, cur, res, 0)
    
    return res

if __name__ == "__main__":
    arr = [1,2,3]
    target = 5

    res = targetSumComb(arr, target)

    for v in res:
        print(" ".join(map(str, v)))
C#
using System;
using System.Collections.Generic;

class GFG {

    // Function to generate all combinations
    // of arr that sums to target.
    static void makeCombination(int[] arr, int remSum, List<int> cur, 
                                 List<List<int>> res, int index) {
        if (remSum == 0) {
            res.Add(new List<int>(cur));
            return;
        }

        // Invalid Case: If remSum is less than 0 or if index >= arr.Length
        if (remSum < 0 || index >= arr.Length)
            return;

        // Add the current element to the combination
        cur.Add(arr[index]);

        // Recur with the same index
        makeCombination(arr, remSum - arr[index], cur, res, index);

        // Remove the current element from the combination
        cur.RemoveAt(cur.Count - 1);
        makeCombination(arr, remSum, cur, res, index + 1);
    }

    // Function to find all combinations of elements
    // in array arr that sum to target.
    static List<List<int>> targetSumComb(int[] arr, int target) {

        // List to store combinations
        List<int> cur = new List<int>();

        // List to store valid combinations
        List<List<int>> res = new List<List<int>>();
        makeCombination(arr, target, cur, res, 0);

        return res;
    }

    static void Main(string[] args) {
        int[] arr = {1,2,3};
        int target = 5;

        List<List<int>> res = targetSumComb(arr, target);

        foreach (var v in res) {
            foreach (int i in v) {
                Console.Write(i + " ");
            }
            Console.WriteLine();
        }
    }
}
JavaScript
// Function to generate all combinations
// of arr that sums to target.
function makeCombination(arr, remSum, cur, res, index) {
    if (remSum === 0) {
        res.push([...cur]);
        return;
    }

    // Invalid Case: If remSum is less than 0 or if index >= arr.length
    if (remSum < 0 || index >= arr.length)
        return;

    // Add the current element to the combination
    cur.push(arr[index]);

    // Recur with the same index
    makeCombination(arr, remSum - arr[index], cur, res, index);

    // Remove the current element from the combination
    cur.pop();
    makeCombination(arr, remSum, cur, res, index + 1);
}

// Function to find all combinations of elements
// in array arr that sum to target.
function targetSumComb(arr, target) {

    // Array to store combinations
    const cur = [];

    // Array to store valid combinations
    const res = [];
    makeCombination(arr, target, cur, res, 0);

    return res;
}

// Driver Code
const arr = [1,2,3];
const target = 5;
const res = targetSumComb(arr, target);

for (const v of res) {
    console.log(v.join(" "));
}

Output
1 1 1 1 1 
1 1 1 2 
1 1 3 
1 2 2 
2 3 

Time Complexity: O(n^(T/M)), where n is the number of candidates, T is the target, and M is the smallest candidate.

Backtracking can be visualized as a DFS on an n-ary tree:

  • Each node represents a choice of candidate, so it can have at most n children.
  • The maximum depth is roughly T / M, because in the worst case we keep adding the smallest candidate until reaching the target.
  • The total number of nodes in an n-ary tree of depth T/M is bounded by n^(T/M), giving the loose upper bound.

Auxiliary Space: O(T / M), because the recursion stack can go as deep as the maximum number of elements in a combination (adding the smallest candidate repeatedly).


Combination Sum | DSA Problem

Explore