144、目标和

题目描述:
给定一个非负整数数组,a1, a2, …, an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。

返回可以使最终数组和为目标数 S 的所有添加符号的方法数。

示例 1:

输入: 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位整数。

这里使用递归来解决
代码:

class Solution {
    //	第一种尝试使用递归
	int temsum = 0;
	int result1 = 0;
	public  int findTargetSumWays(int[] nums, int S) {
		temsum = S;
		get(nums, 0, 0);
		return result1;
           }	
	public void get(int nums[],int current,int index){
		if(index == nums.length && current == temsum ){
			result1 ++;
			return ;
		}
		if(index >= nums.length){
			return;
		}
		current += nums[index];
		get(nums, current, index + 1);
		current =  current - nums[index] - nums[index];
		get(nums, current, index + 1);
	}
	
}

评论说可以使用动态规划来解决
在这里插入图片描述
在这里插入图片描述

排名靠前的代码

public class Solution {
    public int findTargetSumWays(int[] nums, int s) {
        int sum = 0;
        for (int n : nums)
            sum += n;
        // 两种情况找不到结果,找得到的话就用subsetSum去找,证书和是(s + sum) >>> 1,也就是除以2
        return sum < s || (s + sum) % 2 > 0 ? 0 : subsetSum(nums, (s + sum) >>> 1); 
    }   

    public int subsetSum(int[] nums, int s) {
        int[] dp = new int[s + 1]; 
        dp[0] = 1;// 初始记录0的位置为1
        for (int n : nums)
            // 对每个元素,看看他现有能和别的元素相加得到哪些位置的数
            for (int i = s; i >= n; i--)
                dp[i] += dp[i - n]; 
        return dp[s];
    } 
}

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_34446716/article/details/94594465