Given an array of N
nonnegative integers and a target
sum, check if it is possible to obtain target
by choosing some elements of the array and adding them up. (An element can be chosen multiple times).
I tried to come up with a brute force recursive solution. My idea is that for each element, we have 3 choices
Here's my C++ code
bool checkSum(vector<int> &arr,int i, int n, int target)
{
if(target==0)
return true;
if(i>=n or target<0)
return false;
return (checkSum(arr, i+1, n, target) or // don't include current value and move to next
checkSum(arr, i, n, target-arr[i]) or // include current value
checkSum(arr, i+1, n, target-arr[i])); // include current value and move to next
}
This code seems to fail for some testcases
arr = [10,7,0,6,2,6] target = 11
I am not able to find out what is the bug.
Driver Code
int main()
{
int n, target;
cin >> n >> target;
vector<int> arr(n);
for (int i = 0; i < n; i++)
cin >> arr[i];
if (checkSum(arr, 0, n, target))
cout << "YES\n";
else
cout << "NO\n";
return 0;
}
PS: I am not looking for Dynamic Programming solutions as I just want to make my basics right first. It would be nice if I can know what I am missing in this code.
Suppose we have a number target. We have another two numbers A and B. We have to check whether we can get target by adding A and B as many times as we want. So, if the input is like Target = 26 A = 5 B = 7, then the output will be True as we can get 26 by adding A and B like (7 + 7 + 7 + 5).
The sum of the array is 22. Put arr [0] = arr [1] where i=0 and j=1. The sum of this new array is 21 which is odd. Sum of the array is 20. The sum of the array cannot change to odd as all the elements are even.
We have to check whether it is possible to get sum by adding elements present in nums, we may pick a single element multiple times. So, if the input is like nums = [2, 3, 5] sum = 28, then the output will be True as we can get 26 by using 5 + 5 + 5 + 5 + 3 + 3 + 2
If the sum is even, then one of the even numbers can be replaced with an odd number thereby making the sum of the array odd. If there are no odd elements in the array, then the sum of the array cannot be made odd. // sum of the array can be made odd.
First take a large sized array ( which is maximum size of x). Initially keep zero in all it’s indexes. Make 1 at zero index ( we can get zero whatever the array is) . Now, traverse through the whole array and make all possible values as 1. cout << x << " is possible.";
The second recursion is causing the function to recurse infinitely as when arr[i] = 0
, checkSum(arr, i, n, target)
will call checkSum(arr, i, n, target-0)
which will run infinitely.
It is senseless to add 0
more than once, so the only change required is to avoid the second recursion when arr[i] == 0
bool checkSum(vector<int> &arr,int i, int n, int target)
{
if(target==0)
return true;
if(i>=n or target<0)
return false;
return (checkSum(arr, i+1, n, target) or // don't include current value and move to next
(arr[i] ? checkSum(arr, i, n, target-arr[i]) : false) or // include current value
checkSum(arr, i+1, n, target-arr[i])); // include current value and move to next
}
If the array has a non-positive number (such as zero) in it, your solution will never stop iterating.
Thanks to @BillLynch, it seems the code fails when any value is 0. So I just added an extra condition and it seems to work now.
bool checkSum(vector<int> &arr,int i, int n, int target)
{
if(target==0)
return true;
if(i>=n or target<0)
return false;
return (checkSum(arr, i+1, n, target) or // don't include current value and move to next
arr[i]!=0 and // include only if non-zero value
(checkSum(arr, i, n, target-arr[i]) or // include current value
checkSum(arr, i+1, n, target-arr[i]))); // include current value and move to next
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With