算法小白,没学过算法,所有动态规划的题目全部都靠自己一点一点的想,感觉自己弱爆了!!!
看到这道题的时候怎么想都觉得应该是递归的办法来解决,于是写了一版递归的解法,可能是数据量不太复杂所以也accept了,第一版的时候最后一个全0数组的case没有通过,看看提交结果,反正最后一个case了,就随便加了一下。
题目如下:
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.
Note:
- The length of the given array is positive and will not exceed 20.
- The sum of elements in the given array will not exceed 1000.
- Your output answer is guaranteed to be fitted in a 32-bit integer.
思路非常简单直接,对于给定的例子,[1,1,1,1,1] 从数组第一位开始向后扫描,对于5个数的运算结果为3的情况,那么去掉第一个数,(第一个数要么是1,要么是-1,也就是说满足条件的后四个数的运算和要么是4,要么是2),所以就是[1,1,1,1]的结果为4的数量加上[1,1,1,1]的结果为2的数量嘛。以此类推。
我的代码如下:
class Solution {
int[] nums;
public int findTargetSumWays(int[] nums, int S) {
this.nums=new int[nums.length-1];
this.nums=nums;
int index0=0;
while(index0<nums.length)
{
if(nums[index0]!=0)
break;
index0++;
}
if(index0==nums.length)
return (int) Math.pow(2,nums.length);
return fSum(0,S);
}
public int fSum(int begin,int S){
if(begin==nums.length-1){
if(nums[begin]==S||nums[begin]==(-1)*S)
return 1;
else return 0;
}
else{
if(nums[begin]!=0 && (nums[begin]==S||nums[begin]==(-1)*S)){
int index0=begin+1;
int count=0;
while(index0<nums.length){
if(nums[index0]!=0)
break;
else
count++;
index0++;
}
if(index0==nums.length)
return (int)Math.pow(2,count);
}
}
return fSum(begin+1,S-nums[begin])+fSum(begin+1,S+nums[begin]);
}
}
补充一下:后来看了看别人的动态规划的代码,觉得哇还有这样的操作呀,我简单记录一下思路,回头再做一遍这道题吧。
对于给定数组,比如[1,1,1,1,1],不管如何运算,其最大值不会超过5,最小值不会超过-5.也就是说不管怎么运算其结果也就是-5到5之间。因此结果可以有一个数组,类比一下哈,sum[-5],sum[-4]...sum[0]...sum[4],sum[5]。 先假设结果是0,然后从数组第一个数开始向后扫描,只有两种情况,0+1,或者0-1,因此扫描到第一个数,结果数组中sum[-1]=1,sum[1]=1。然后扫描第二个数,还是1,存在4种结果-1-1,-1+1,1-1,1+1,因此当扫描第二个数的时候,sum[-2]=1,sum[0]=2,sum[2]=1,以此类推。
以此来实现了动态规划,仍然是从左向右扫描,但是不是用一个数来计算而是用一组数据来记录。我决定自己把这种思路称为反向动态规划好了。哈哈哈哈哈哈红红火火火....