题目描述
给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/target-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题目分析
其实自己也想到了思路,这次的转化条件挺好想的,dp[i] = dp[i - nums[j]] + dp[i + nums[j]]。由于涉及了i和j,因此虽然只有一个数组,但还是可以用二维数组dp[i] [j]。
dp[i] [j]: 用nums索引为前i个元素组合出j的可能种数。
代码实现
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for(int num : nums) {
sum += Math.abs(num);
}
if(Math.abs(target) > sum) return 0;
int cols = 2 * sum + 1; // 11列:[-sum, sum]
int rows = nums.length; // 5 列:[nums[0], nums[n]]
// dp[i][j] 用前i个元素合成j的可能种数
int[][] dp = new int[rows][cols]; // 5 * 11列
for(int i = 0; i < rows; i++) {
dp[i][0] = 0; // 0列全为0
}
for(int j = 0; j < cols; j++) {
dp[0][j] = 0; // 0行全为0
}
dp[0][sum - nums[0]] = 1;
dp[0][sum + nums[0]] = nums[0] == 0 ? 2 :1; // 如果为 0 的话 则有两种
return dp[rows - 1][sum + target];
}
}
复杂度分析
时间复杂度:O(MN)。M为数组元素个数,N为元素绝对值总和。