决定做一期LeetCode 热题100算法题的分享,我会对每一行代码进行注释,希望对于入门读者有一些帮助。
问题描述:
给你一个整数数组 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
中心思想:
关键词:动态规划
步骤一:定义
dp[i][j] 代表i之前的元素累加和为j的次数
步骤二:初始化
dp[0][nums[0] + 1000] = 1;
dp[0][-nums[0] + 1000] = 1;
步骤三:转移方程
dp[i][j] = dp[i-1][j-num[i]]+dp[i-1][j+num[i]];
步骤四:返回结果
return dp[n-1][s+1000]
最终代码实现:
class Solution {
public int findTargetSumWays(int[] nums, int S) {
int m = nums.length;
int[][] dp = new int[m][2001]; //2001个
dp[0][nums[0] + 1000] = 1;
dp[0][-nums[0] + 1000] = 1;
for (int i = 1; i < m; i++) {
for (int j = -1000; j <= 1000; j++) {
if (dp[i - 1][j + 1000] > 0) { //为社么要加这个判断????????,前i-1个元素累加和为j+1000的次数,确保前i-1个元素已经遍历完
dp[i][j + 1000] = dp[i - 1][j + 1000 - nums[i]] + dp[i - 1][j + 1000 + nums[i]];
}
}
}
return S>1000? 0: dp[m-1][S+1000];
}
}