【Java】LeetCode 494. 目标和

给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
示例:
输入:nums: [1, 1, 1, 1, 1], S: 3
输出:5
解释:
-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
一共有5种方法让最终目标和为3。
提示:
数组非空,且长度不会超过 20 。
初始的数组的和不会超过 1000 。
保证返回的最终结果能被 32 位整数存下。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/target-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

递归!

数组Nums中有N个数,目标值为S,取最后一个数(其实任意数均可,这里为了方便取最后一个)x,对Nums目标为S的问题可以转化为:

Nums`数组(Nums拿走最后一个数后的新数组)中N-1个数,同样规则目标数为S±x,方法有多少种。

容易知道,上述问题两个解的和,即为所求原问题的解。

而拆分出来的两个问题可以继续拆分(套娃),这就是可以使用递归的基础

递归什么时候结束呢?

拆到数组中只有一个数了,也就是拆了N-1次,问题变成了2N-1 个原子问题,这时候判断,S和所剩最后一个数绝对值是否相等即可

需要注意:若最后一个数为0且S=0的情况,应该是两种方法,因为±0=0。
class Solution {
     
    public int findTargetSumWays(int[] nums, int S) {
     
        return h(nums,S,nums.length-1);
    }
    public int h(int[] nums, int S,int index) {
     
        if(index!=0){
     
        //如果数组下标不为0,就拆分为更小的数组
            return h(nums,S+nums[index],index-1)+h(nums,S-nums[index],index-1);
        }else{
     
        //数组为0,判断S和x绝对值是否相等,不想等则不满足条件返回0
        //若等于0则正负号均可返回2
        //否则返回1
            if(Math.abs(nums[0])==Math.abs(S)){
     
                if(S==0){
     
                    return 2;
                }else{
     
                    return 1;
                }
            }else{
     
                return 0;
            }
        }
    }
}

你可能感兴趣的:(有趣的面试题,算法,java,leetcode)