c++recursioncombinations

Check if a target sum is possible given a vector of values


The problem is to check if it is possible to get a given targetSum from the elements of a given array. Each element should be included once only (if included).

The code is a brute force approach using recursion. I wanted to implement the idea that if the current element makes the sum equal to targetSum then return true. If the current element added to currSum is less than targetSum then check if including it returns true. If it does, I will return true, otherwise I will check without including it in currSum.

The thing is that the program gives a correct answer for some vectors, and a wrong answer for some other vectors.

The recursive function:

bool checkSum(vector<int> v, int idx, int currSum, int targetSum){
    if(idx == v.size()) return false;
    if(currSum+v[idx] == targetSum) return true;
    if(currSum+v[idx] > targetSum) return false;
    bool ans = checkSum(v, idx+1, currSum+v[idx], targetSum);
    if(ans) return true;
    ans = checkSum(v, idx+1, currSum, targetSum);
    return ans;
}

For this input:

v : [ 4 18 5 9 ]
targetSum : 14

The output is false.

For this input:

v : [ 4 11 5 9 ]
targetSum : 14

The output is true.

I can't figure out what is possibly going wrong here.

The driver code:

int main(){
    int n;
    cin>>n;
    vector<int> v(n);
    for(auto &it:v){
        cin>>it;
    }
    int targetSum;
    cin>>targetSum;
    cout<<(checkSum(v,0,0,targetSum)?"true":"false");
}

Solution

  • You need to continue checking the rest of the vector even if the current number is larger than the sum. Currently you are returning false as soon as the current number is larger than the target sum.

    bool checkSum(vector<int> v, int idx, int currSum, int targetSum){
        if(idx == v.size()) return false;
        if(currSum+v[idx] == targetSum) return true;
        if(currSum+v[idx] > targetSum) return checkSum(v, idx+1, currSum, targetSum);
        bool ans = checkSum(v, idx+1, currSum+v[idx], targetSum);
        if(ans) return true;
        ans = checkSum(v, idx+1, currSum, targetSum);
        return ans;
    }