LeetCode 494:目标和(Target Sum)—— 题解 ✅

LeetCode 494:目标和(Target Sum)------ 题解 ✅

🔗 题目链接

👉 https://leetcode.cn/problems/target-sum/


📖 内容概要

给定一个非负整数数组 nums 和一个整数 target

你可以在每个数字前加 +-,使计算结果等于 target

返回所有可能的表达式数量。

✅ 0/1 背包(计数问题)

✅ 数学转化是关键

✅ 面试高频题


💡 解题思路(核心)

一、关键数学转化(非常重要)

设:

  • 正数和为 P
  • 负数绝对值和为 N

则有:

复制代码
P - N = target
P + N = sum

解得:

复制代码
P = (sum + target) / 2

👉 问题转化为:

从数组中选出若干数,使其和正好等于 P


二、不可行的情况(剪枝)

情况 原因
(sum + target) 为奇数 无法整除
` target
java 复制代码
if ((sum + target) % 2 == 1) return 0;
if (Math.abs(target) > sum) return 0;

三、DP 定义

java 复制代码
dp[j] = 和为 j 的方案数

四、状态转移方程

java 复制代码
dp[j] += dp[j - nums[i]];

✅ 每个数只能用一次

✅ 倒序遍历(0/1 背包)


五、初始化

java 复制代码
dp[0] = 1;

什么都不选,是一种方案


✅ AC 代码(Java)

java 复制代码
class Solution {
    public int findTargetSumWays(int[] nums, int target) {
        int sum = 0;
        for (int a : nums) {
            sum += a;
        }

        int left = (sum + target) / 2;

        // 剪枝
        if ((sum + target) % 2 == 1) return 0;
        if (Math.abs(target) > sum) return 0;

        int[] dp = new int[left + 1];
        dp[0] = 1;

        // 0/1 背包(计数)
        for (int i = 0; i < nums.length; i++) {
            for (int j = left; j >= nums[i]; j--) {
                dp[j] += dp[j - nums[i]];
            }
        }
        return dp[left];
    }
}

⏱️ 复杂度分析

指标 复杂度
时间复杂度 O(n × sum)
空间复杂度 O(sum)

🔍 与 416 / 1049 的对比

题目 目标
416. 分割等和子集 是否存在
1049. 最后一块石头 II 最小差值
494. 目标和 方案数

✅ 三题本质都是 子集和问题

✅ 区别在于 DP 含义不同


✅ 一句话总结

把"加减符号问题"转化为"子集和为 P 的方案数问题",再用 0/1 背包计数。


📌 面试加分点(建议记住)

  • ✅ 为什么是 (sum + target) / 2
  • ✅ 为什么 dp[0] = 1
  • ✅ 为什么是 += 而不是 max
  • ✅ 与回溯法的对比(会超时)
相关推荐
圣保罗的大教堂4 小时前
leetcode 3867. 数对的最大公约数之和 中等
leetcode
To_OC6 小时前
LC 15 三数之和:双指针不难,难的是把去重做对
javascript·算法·leetcode
renhongxia18 小时前
世界模型,是“空中楼阁”还是AGI的“最后一块拼图”?
运维·服务器·数据库·人工智能·算法·agi
G.O.G.O.G9 小时前
LeetCode SQL 从入门到精通(MySQL)06(上)
数据库·sql·mysql·leetcode
zephyr0510 小时前
动态规划-最长上升子序列问题
算法·动态规划
闪电悠米11 小时前
力扣hot100-56.合并区间-排序详解
数据结构·算法·leetcode·贪心算法·排序算法
卡提西亚12 小时前
leetcode-1438. 绝对差不超过限制的最长连续子数组
算法·leetcode·职场和发展
Java面试题总结12 小时前
LeetCode 93.复原IP地址
算法·leetcode·职场和发展·.net
从零开始的代码生活_13 小时前
C++ 多态详解:虚函数、动态绑定、抽象类与虚表原理
开发语言·c++·后端·学习·算法
Tisfy13 小时前
LeetCode 3867.数对的最大公约数之和:按题目说的做(gcd)
算法·leetcode·题解·模拟·最大公约数·gcd