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.
Example 1:
Input: nums is [1, 1, 1, 1, 1], S is 3.
Output: 5
Explanation:
-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
There are 5 ways to assign symbols to make the sum of nums be target 3.
思路:暴力解,就是DFS,暴力搜索所有的空间,2^n
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int[] res = new int[]{0};
dfs(nums, 0, 0, target, res);
return res[0];
}
private void dfs(int[] nums, int cursum, int i, int target, int[] res) {
if(i == nums.length) {
if(cursum == target) {
res[0]++;
}
return;
}
//加法;
cursum += nums[i];
dfs(nums, cursum, i + 1, target, res);
cursum -= nums[i];
//减法;
cursum -= nums[i];
dfs(nums, cursum, i + 1, target, res);
cursum += nums[i];
}
}
思路2: index + cursum的二维数组,因为给的array全部是正数,那么range就是[-sum, sum],我整体平移,所以起点就是sum,target就成了 target + sum; O(N * Sum);
class Solution {
public int findTargetSumWays(int[] nums, int target) {
int sum = 0;
for(int num: nums) {
sum += num;
}
// -sum, sum
int n = nums.length;
int[][] memo = new int[n + 1][2 * sum + 1];
// 把-sum,sum shift一下,那么起点就是sum,注意target的起点也要挪动target + sum;
return dfs(nums, 0, sum, memo, target + sum);
}
private int dfs(int[] nums, int i, int cursum, int[][] memo, int target) {
if(i == nums.length) {
return cursum == target ? 1 : 0;
}
if(memo[i][cursum] != 0) {
return memo[i][cursum];
}
int res = dfs(nums, i + 1, cursum + nums[i], memo, target)
+ dfs(nums, i + 1, cursum - nums[i], memo, target);
memo[i][cursum] = res;
return res;
}
}