leetcode494 TargetSum 非动态规划的解法

算法小白,没学过算法,所有动态规划的题目全部都靠自己一点一点的想,感觉自己弱爆了!!!


看到这道题的时候怎么想都觉得应该是递归的办法来解决,于是写了一版递归的解法,可能是数据量不太复杂所以也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:

  1. The length of the given array is positive and will not exceed 20.
  2. The sum of elements in the given array will not exceed 1000.
  3. Your output answer is guaranteed to be fitted in a 32-bit integer.
https://leetcode.com/problems/target-sum/description/


思路非常简单直接,对于给定的例子,[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,以此类推。


以此来实现了动态规划,仍然是从左向右扫描,但是不是用一个数来计算而是用一组数据来记录。我决定自己把这种思路称为反向动态规划好了。哈哈哈哈哈哈红红火火火....

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值