【路飞】494. 目标和

71 阅读1分钟

题目描述

494. 目标和

难度 中等

给你一个整数数组 nums 和一个整数 target 。

向数组中的每个整数前添加 '+' 或 '-' ,然后串联起所有整数,可以构造一个 表达式 :

  • 例如,nums = [2, 1] ,可以在 2 之前添加 '+' ,在 1 之前添加 '-' ,然后串联起来得到表达式 "+2-1" 。

返回可以通过上述方法构造的、运算结果等于 target 的不同 表达式 的数目。

示例 1:

输入: nums = [1,1,1,1,1], target = 3
输出: 5
解释: 一共有 5 种方法让最终目标和为 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

示例 2:

输入: nums = [1], target = 1
输出: 1

提示:

  • 1 <= nums.length <= 20
  • 0 <= nums[i] <= 1000
  • 0 <= sum(nums[i]) <= 1000
  • -1000 <= target <= 1000

解析

解法一
使用回溯算法,对-号或者+号做选择

function findTargetSumWays(nums, target) {
  if (!nums.length) {
    return 0;
  }
  return dfs(nums, 0, target);
  function dfs(nums, index, target) {
    if (index === nums.length) {
      return target === 0 ? 1 : 0;
    }
    // 给 nums[i] 选择 - 号或者 + 号
    const count =
      dfs(nums, index + 1, target - nums[index]) +
      dfs(nums, index + 1, target + nums[index]);
    return count;
  }
}

解法二
对解法一进行优化,带了缓存

function findTargetSumWays(nums, target) {
  if (!nums.length) {
    return 0;
  }
  const map = new Map();
  return dfs(nums, 0, target);
  function dfs(nums, index, target) {
    if (index === nums.length) {
      return target === 0 ? 1 : 0;
    }
    const key = `${index}-${target}`;
    if (map.has(key)) {
      return map.get(key);
    }
    const count =
      dfs(nums, index + 1, target - nums[index]) +
      dfs(nums, index + 1, target + nums[index]);
    map.set(key, count);
    return count;
  }
}