每周LeetCode算法题(十八)
题目: 494. Target Sum
You are given a list of non-negative integers, a1, a2, …, an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol.
Find out how many ways to assign symbols to make sum of integers equal to target S.
解法分析
本题一开始我的想法是递归性的,即从第一个元素开始,由正负号可以分为两个节点,到第二个元素时,再继续分为两个节点,这样有n个元素就有最终的n^2条路径,但这试过发现到了n=20时就超时了。
但是由于很多这样的路径最终殊途同归,得到一样的和,而正负的数组的和之间(因为最大能到正的和,最小能到负的和,不会在此区间之外了)的区间是较短的,要是在这个区间内,每次每条路径都记录一步,那么n步之后能到的能到目标点的路径数就显示出来了。
C++代码
class Solution {
public:
int findTargetSumWays(vector<int>& nums, int S) {
int len = nums.size();
if (len == 0) {
return 0;
}
int sum = 0;
for (int i = len - 1; i >= 0; i--) {
sum += nums[i];
}
if (S > sum || S < -sum) {
return 0;
}
vector< vector<int> > dp;
dp.resize(len, vector<int>(2 * sum + 1, 0));
dp[0][sum + nums[0]]++;
dp[0][sum - nums[0]]++;
for (int i = 1; i < len; i++) {
for (int j = 0; j < 2 * sum + 1; j++) {
if (j + nums[i] < 2 * sum + 1) {
dp[i][j + nums[i]] += dp[i - 1][j];
}
if (j - nums[i] >= 0) {
dp[i][j - nums[i]] += dp[i - 1][j];
}
}
}
return dp[len - 1][sum + S];
}
};