Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions include/0005_DynamicProgramming/0017_TargetSum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once

#include<vector>
#include<numeric>
using namespace std;

/*
Pattern 2
Subset / 0-1 Knapsack

Description
Given an array arr[] of length N and an integer target.
You want to build an expression out of arr[] by adding one of the symbols '+' and '-' before each integer in arr[] and then concatenate all the integers.
Return the number of different expressions that can be built, which evaluates to target.

Example:

Input : N = 5, arr[] = {1, 1, 1, 1, 1}, target = 3
Output: 5
Explanation:
There are 5 ways to assign symbols to
make the sum of array be target 3.

-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

Input: N = 1, arr[] = {1}, target = 1
Output: 1
*/

namespace TargetSum
{
class DynamicProgramming
{
private:
int recursiveFindTotalWaysHelper(vector<int>& nums, int currentSum, int targetSum, int index);
int dpFindTotalWays();
public:
int recursiveFindTotalWays(vector<int> nums, int target);
int dpFindTotalWays(vector<int> nums, int target);
};
}
71 changes: 71 additions & 0 deletions src/0005_DynamicProgramming/0017_TargetSum.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <0005_DynamicProgramming/0017_TargetSum.h>

namespace TargetSum
{
int DynamicProgramming::recursiveFindTotalWaysHelper(vector<int>& nums, int currentSum, int targetSum, int index)
{
// Base case
if (currentSum == targetSum && index == nums.size())
{
return 1;
}

if (index >= nums.size())
{
return 0;
}

// Return total count of two possible ways while considering the current element
// 1. Add the current element to currentSum
// 2. Subtract the current element from currentSum
return (
this->recursiveFindTotalWaysHelper(nums, currentSum + nums[index], targetSum, index + 1)
+
this->recursiveFindTotalWaysHelper(nums, currentSum - nums[index], targetSum, index + 1));
}


int DynamicProgramming::recursiveFindTotalWays(vector<int> nums, int target)
{
return this->recursiveFindTotalWaysHelper(nums, 0, target, 0);
}

int DynamicProgramming::dpFindTotalWays(vector<int> nums, int target)
{
int totalSum = accumulate(nums.begin(), nums.end(), 0);

if (abs(target) > totalSum)
{
return 0;
}

int totalSumWithTarget = totalSum + target;
if (totalSumWithTarget % 2 != 0)
{
return 0;
}

int targetSubsetSum = totalSumWithTarget / 2;
int noOfElements = nums.size();
vector<vector<int>> dp(noOfElements + 1, vector<int>(targetSubsetSum + 1, 0));

dp[0][0] = 1;

for (int i = 1; i <= noOfElements; i++)
{
for (int j = 0; j <= targetSubsetSum; j++)
{
// Considering excluding the current element
dp[i][j] = dp[i - 1][j];

// Case to include the current element
if (nums[i - 1] <= j)
{
dp[i][j] += dp[i - 1][j - nums[i - 1]];
}
}
}

return dp[noOfElements][targetSubsetSum];
}
}
1 change: 1 addition & 0 deletions src/0005_DynamicProgramming/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(0005DYNAMICPROGRAMMING_SOURCES
0014_SubsetSumProblem.cc
0015_CountSubsetsForSum.cc
0016_PartitionEqualSubsetSum.cc
0017_TargetSum.cc

)

Expand Down
50 changes: 50 additions & 0 deletions tests/0005_DynamicProgramming/0017_TargetSumTest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <gtest/gtest.h>
#include <0005_DynamicProgramming/0017_TargetSum.h>

namespace TargetSum
{
TEST(TargetSum, TC0001)
{
// Arrange
DynamicProgramming dp;
vector<int> nums = { 1, 1, 1, 1, 1 };
int target = 3;
int expectedResult = 5;

// Act
int actualResult = dp.recursiveFindTotalWays(nums, target);

// Assert
ASSERT_EQ(expectedResult, actualResult);
}

TEST(TargetSum, TC0002)
{
// Arrange
DynamicProgramming dp;
vector<int> nums = { 1, 1, 1, 1, 1 };
int target = 3;
int expectedResult = 5;

// Act
int actualResult = dp.dpFindTotalWays(nums, target);

// Assert
ASSERT_EQ(expectedResult, actualResult);
}

TEST(TargetSum, TC0003)
{
// Arrange
DynamicProgramming dp;
vector<int> nums = { 1, 1, 1, 1, 1 };
int target = -1000;
int expectedResult = 0;

// Act
int actualResult = dp.dpFindTotalWays(nums, target);

// Assert
ASSERT_EQ(expectedResult, actualResult);
}
}
1 change: 1 addition & 0 deletions tests/0005_DynamicProgramming/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_executable(
0014_SubsetSumProblemTest.cc
0015_CountSubsetsForSumTest.cc
0016_PartitionEqualSubsetSumTest.cc
0017_TargetSumTest.cc

)

Expand Down
Loading