combinations
number theory
sum calculation
algorithm
mathematics

Finding all possible combinations of numbers to reach a given sum

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Finding all possible combinations of numbers to reach a given sum is a classic problem in computer science and mathematics. This problem has practical applications in areas like finance, optimization, and cryptography. The goal is to find unique sets of numbers from a given list that add up to a specific target sum. In this article, we explore different techniques to solve this problem, including recursive and iterative approaches.

Basic Concepts

Before diving into algorithms, it's essential to understand some fundamental concepts:

  • Target Sum: The specific sum that we aim to achieve by adding numbers from a given list.
  • Combination: A subset of numbers that adds up precisely to the target sum.
  • Unique Combinations: Combinations that differ from each other by at least one number. The order of numbers within a combination does not matter.

Recursive Approach

One intuitive way to solve the problem is through recursion. The recursive method explores all possible combinations by adding elements one by one and checks if they meet the target sum.

Example Algorithm

Consider a list of numbers [2, 3, 6, 7] and a target sum of 7. We need to find all combinations that sum to 7.

python
1def find_combinations_recursive(candidates, target, index, path, results):
2    if target == 0:
3        results.append(path)
4        return
5    for i in range(index, len(candidates)):
6        if candidates[i] > target:
7            break
8        find_combinations_recursive(candidates, target - candidates[i], i, path + [candidates[i]], results)
9
10def combination_sum(candidates, target):
11    candidates.sort()
12    results = []
13    find_combinations_recursive(candidates, target, 0, [], results)
14    return results

Explanation

  • Base Case: If the target is zero, the current path is a valid combination.
  • Recursive Case: For each number at a given index, subtract it from the target, and recursively attempt to reach the target with the remaining numbers.
  • Pruning: If a number is greater than the remaining target, skip it to avoid unnecessary calculations.

Iterative Approach

An iterative solution typically uses dynamic programming or backtracking techniques. This approach involves building up solutions from smaller subproblems.

Example Algorithm

A dynamic programming table can be used to store all combinations up to the given target.

python
1def combination_sum_dp(candidates, target):
2    dp = [[] for _ in range(target + 1)]
3    dp[0] = [[]]
4    for candidate in candidates:
5        for current_sum in range(candidate, target + 1):
6            for combination in dp[current_sum - candidate]:
7                dp[current_sum].append(combination + [candidate])
8    return dp[target]

Explanation

  • DP Table: Each entry in the table corresponds to all combinations that sum to that index.
  • Combining Solutions: For each candidate, and every potential sum, build new combinations using previously calculated subproblems.

Comparing Approaches

ApproachComplexityAdvantagesDisadvantages
RecursiveExponentialSimple to implement, intuitiveCan be inefficient for large datasets
Iterative DPPolynomialEfficient, suitable for larger targetsInitial setup overhead

Advanced Techniques

Memoization

Using recursion with memoization can significantly improve the efficiency by storing previously calculated results. This technique prevents redundant calculations, thus transforming an exponential solution to a manageable one.

Constraints Handling

  • Bounded Combinations: Sometimes, constraints like the number of times each element can be used are imposed. Adjusting recursion or iteration to respect these constraints is key to broadening the problem’s applicability.
  • Negative Numbers: Incorporate negative numbers in candidates which can make the problem more challenging.

Conclusion

Finding all possible combinations of numbers to reach a given sum combines elegant recursion with practical dynamic programming techniques. By understanding and applying these methods, one can effectively address a variety of real-world problems. Both recursive and iterative solutions have their places, and choosing the right approach often depends on the specific requirements and constraints of the problem at hand.


Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.