We have a list of numbers, let's say: [ 2, 3, 5 ] and we have a targetSum, let's say: 8
Our goal, then, is to pick numbers from the list in such a way that the sum of the numbers would lead to targetSum
I'll explain my code first, I wrote a simple c++ code for the same, it uses recursion and backtracking ( without memoization ). It does the following:
- We subdivide our original problem by reducing the targetSum by each number at each recursion
- Visualizing this in the form of a tree is useful, we also keep track of what number's we have substracted so far, and we keep pushing and popping accordingly
- Once we hit the base case of 0, meaning it's possible to create the sum, we make a note of the current numbers we have recursed
- This process goes on until we have gone through all of the possibilities
Code:
#include<iostream>
#include<vector>
using namespace std;
bool bestSum( int targetSum, vector<int> &holder, vector<vector<int>> &combinations,
vector<int> &path )
{
if( targetSum == 0 )
{
combinations.push_back( path );
return true;
}
if( targetSum < 0 )
{
return false;
}
bool possible = false;
for( int i = 0; i < holder.size(); i++ )
{
int remainder = targetSum - holder[i];
path.push_back(holder[i]);
cout << "After pushing:";
for( int j = 0; j < path.size(); j++ )
{
cout << path[j] << " ";
}
cout << endl;
bool verdict = bestSum( remainder, holder, combinations, path );
if( verdict == true )
{
possible = true;
}
path.pop_back();
cout << "After popping:";
for( int j = 0; j < path.size(); j++ )
{
cout << path[j] << " ";
}
cout << endl;
}
return possible;
}
int main()
{
vector<int> holder = { 2, 3, 5 };
int targetSum = 8;
vector<vector<int>> combinations;
vector<int> path;
bool verdict = bestSum( targetSum, holder, combinations, path );
for( int i = 0; i < combinations.size(); i++ )
{
for( int j = 0; j < combinations[i].size();j++)
{
cout << combinations[i][j] << " ";
}
cout << endl;
}
return 0;
}
(ignoring the printing statements) Talking about time complexity, it should be: exponential, without memoization And at most small degree polynomial, with memoization
Combing back to the original problem, currently my code produces all of the possible combinations, for example, with the numbers list and targetSum presented at the start of this article, we would get: 2,3,3 and 3,3,2 as two different combinations. But we know that they aren't unique
My question is, is it possible to find all unique combination of numbers whilst keeping the logic of my code consistent?