美文网首页
动态九:目标和

动态九:目标和

作者: 程一刀 | 来源:发表于2021-08-30 10:21 被阅读0次

    题目地址: https://leetcode-cn.com/problems/target-sum/
    题目描述:
    给定一个非负整数数组,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 位整数存下。
    参考代码:

    // 二维数组
    class Solution{
    public:
        int findTargetSumWays(vector<int>& nums, int target) {
            int sum = 0;
            for (int i = 0; i<nums.size(); i++) {
                sum = sum + nums[i];
            }
            // a + b = s a-b = target , a = (s + target) / 2
            //转化为: 从 nums 几个数 使 其相加等于 a
            int a = sum + target;
            if ( a < 0) { // 边界情况处理
                return 0;
            }
            if (a %2 != 0) {
                return 0;
            }
            a = a /2;
            // 第一种 dp[i][j] (前i个数,和为j) = dp[i-1][j] + d[i-1][j-num[i]]
            vector<vector<int>> dp = vector<vector<int>>(nums.size()+1,vector<int>(a+1,0));
            // 第一行初始化 选中时候,使 其为1
            if (nums[0] <=a) {
                dp[0][nums[0]] = 1;
            }
            if (nums[0] ==0 ){  //边界情况处理
                dp[0][nums[0]] = 2;
            } else{
                dp[0][0] = 1;
            }
            
            
            for (int i = 1; i< nums.size(); i++) {
                for (int j = 0; j<=a; j++) { // j<=a
                    if (j >= nums[i]) {
                        dp[i][j] = dp[i-1][j] + dp[i-1][j-nums[i]];
                    } else {
                        dp[i][j] = dp[i-1][j];
                    }
                }
            }
            return dp[nums.size()-1][a];
        }
    };
    
    //一维数组
    class Solution {
    public:
        int findTargetSumWays(vector<int>& nums, int S) {
            int sum = 0;
            for (int i = 0; i<nums.size(); i++) {
                sum = sum + nums[i];
            }
            int bagsise = sum + S;
            if (bagsise < 0) {
                return 0;
            }
            if (bagsise % 2 == 1) {
                return 0;
            }
            bagsise = bagsise / 2;
            vector<int> dp = vector<int>(bagsise+1,0);
            // dp[i] = dp[i] +dp[i-num[i]]  和的大小为i的 数量
            dp[0] = 1;
            for (int i = 0; i< nums.size(); i++) {
                for (int j = bagsise; j >= nums[i]; j--) {
                    dp[j] = dp[j] + dp[j-nums[i]];
                }
            }
            return dp[bagsise];
        }
    
    };
    
    
    
    

    参考链接: https://github.com/youngyangyang04/leetcode-master/blob/master/problems/0494.%E7%9B%AE%E6%A0%87%E5%92%8C.md

    相关文章

      网友评论

          本文标题:动态九:目标和

          本文链接:https://www.haomeiwen.com/subject/nkymiltx.html