Welcome to Subscribe On Youtube
494. Target Sum
Description
You are given an integer array nums
and an integer target
.
You want to build an expression out of nums by adding one of the symbols '+'
and '-'
before each integer in nums and then concatenate all the integers.
- For example, if
nums = [2, 1]
, you can add a'+'
before2
and a'-'
before1
and concatenate them to build the expression"+2-1"
.
Return the number of different expressions that you can build, which evaluates to target
.
Example 1:
Input: nums = [1,1,1,1,1], target = 3 Output: 5 Explanation: There are 5 ways to assign symbols to make the sum of nums 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
Example 2:
Input: nums = [1], target = 1 Output: 1
Constraints:
1 <= nums.length <= 20
0 <= nums[i] <= 1000
0 <= sum(nums[i]) <= 1000
-1000 <= target <= 1000
Solutions
Dynamic programming.
It is similar to the 0-1 Knapsack problem, except that the index may appear negative, which requires special handling.
-
class Solution { public int findTargetSumWays(int[] nums, int target) { int s = 0; for (int v : nums) { s += v; } if (s < target || (s - target) % 2 != 0) { return 0; } int n = (s - target) / 2; int[] dp = new int[n + 1]; dp[0] = 1; for (int v : nums) { for (int j = n; j >= v; --j) { dp[j] += dp[j - v]; } } return dp[n]; } }
-
class Solution { public: int findTargetSumWays(vector<int>& nums, int target) { int s = accumulate(nums.begin(), nums.end(), 0); if (s < target || (s - target) % 2 != 0) return 0; int n = (s - target) / 2; vector<int> dp(n + 1); dp[0] = 1; for (int& v : nums) for (int j = n; j >= v; --j) dp[j] += dp[j - v]; return dp[n]; } };
-
class Solution: def findTargetSumWays(self, nums: List[int], target: int) -> int: s = sum(nums) if s < target or (s - target) % 2 != 0: return 0 n = (s - target) // 2 dp = [0] * (n + 1) dp[0] = 1 for v in nums: for j in range(n, v - 1, -1): dp[j] += dp[j - v] return dp[-1]
-
func findTargetSumWays(nums []int, target int) int { s := 0 for _, v := range nums { s += v } if s < target || (s-target)%2 != 0 { return 0 } n := (s - target) / 2 dp := make([]int, n+1) dp[0] = 1 for _, v := range nums { for j := n; j >= v; j-- { dp[j] += dp[j-v] } } return dp[n] }
-
/** * @param {number[]} nums * @param {number} target * @return {number} */ var findTargetSumWays = function (nums, target) { let s = 0; for (let v of nums) { s += v; } if (s < target || (s - target) % 2 != 0) { return 0; } const m = nums.length; const n = (s - target) / 2; let dp = new Array(n + 1).fill(0); dp[0] = 1; for (let i = 1; i <= m; ++i) { for (let j = n; j >= nums[i - 1]; --j) { dp[j] += dp[j - nums[i - 1]]; } } return dp[n]; };
-
impl Solution { #[allow(dead_code)] pub fn find_target_sum_ways(nums: Vec<i32>, target: i32) -> i32 { let mut sum = 0; for e in &nums { sum += *e; } // -x + (sum - x) = target <-> -2 * x + sum = target <-> 2 * x = sum - target if sum < target || (sum - target) % 2 != 0 { // There is no way to get any expression in this case return 0; } let n = nums.len(); let m = (sum - target) / 2; let mut dp: Vec<Vec<i32>> = vec![vec![0; m as usize + 1]; n + 1]; // Initialize the dp vector dp[0][0] = 1; // Begin the actual dp phase for i in 1..=n { for j in 0..=m as usize { // nums[i - 1] is not included dp[i][j] = dp[i - 1][j]; if nums[i - 1] <= (j as i32) { // nums[i - 1] is included dp[i][j] += dp[i - 1][j - (nums[i - 1] as usize)]; } } } dp[n][m as usize] } }
-
function findTargetSumWays(nums: number[], target: number): number { const s = nums.reduce((a, b) => a + b, 0); if (s < target || (s - target) % 2) { return 0; } const [m, n] = [nums.length, ((s - target) / 2) | 0]; const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0)); f[0][0] = 1; for (let i = 1; i <= m; i++) { for (let j = 0; j <= n; j++) { f[i][j] = f[i - 1][j]; if (j >= nums[i - 1]) { f[i][j] += f[i - 1][j - nums[i - 1]]; } } } return f[m][n]; }