LeetCode 494 目标和

LeetCode 494 目标和

🟡中等

https://leetcode.cn/problems/target-sum/

显然可以用回溯求解

class Solution {

public:

    vector<int> loc_nums;

    vector<int> path;

    int num =0;

    void wri_at_index(int index,int max_index,int sum, int target){

        if(index==max_index){

            if(sum==target){

                num+=1;

                return;

            }

            return;

        }

        path.push_back(0+loc_nums[index]);

        wri_at_index(index+1, max_index,sum+loc_nums[index],target);

        path.pop_back();

        path.push_back(0-loc_nums[index]);

        wri_at_index(index+1, max_index, sum-loc_nums[index],target);

        path.pop_back();

    }

    int findTargetSumWays(vector<int>& nums, int target) {

        loc_nums = nums;

        wri_at_index(0,nums.size(),0,target);

        return num;

    }

};

但是,设原数组和为sum,加上正负号后的和为target,那么有:正+正 = sum,正+负 = target,则正 = (sum+target)/2,那么转化为背包问题。

class Solution {

public:

    int add_pack(vector<int>& nums,int index,int cap){

        if(cap ==0) return 1;

        if(index==nums.size()) {

            return 0;

        }

        if(cap>=nums[index]){

            return add_pack(nums,index+1,cap)+add_pack(nums,index+1,cap-nums[index]);

        }else{

            return add_pack(nums,index+1,cap);

        }

    }

    int findTargetSumWays(vector<int>& nums, int target) {

        int sum = accumulate(nums.begin(),nums.end(),0);

        if((sum+target)%2){

            return 0;

        }

        return add_pack(nums,0,(sum+target)/2);

    }

};

这里出现了错误,cap等于0不能提前截断 ,这种针对本层输入的,一定要走到最后也就是index到最后才能返回,中途不能返回

修改后

class Solution {

public:

    int add_pack(vector<int>& nums,int index,int cap){

        // if(cap ==0) return 1;

        if(index==nums.size()) {

            if(cap==0) return 1;

            return 0;

        }

        if(cap>=nums[index]){

            return add_pack(nums,index+1,cap)+add_pack(nums,index+1,cap-nums[index]);

        }else{

            return add_pack(nums,index+1,cap);

        }

    }

    int findTargetSumWays(vector<int>& nums, int target) {

        int sum = accumulate(nums.begin(),nums.end(),0);

        if((sum+target)%2){

            return 0;

        }

        return add_pack(nums,0,(sum+target)/2);

    }

};

进一步修改为动态规划

class Solution {

public:

    int add_pack(vector<int>& nums,int index,int cap){

        // if(cap ==0) return 1;

        if(index==nums.size()) {

            if(cap==0) return 1;

            return 0;

        }

        if(cap>=nums[index]){

            return add_pack(nums,index+1,cap)+add_pack(nums,index+1,cap-nums[index]);

        }else{

            return add_pack(nums,index+1,cap);

        }

    }

    int findTargetSumWays(vector<int>& nums, int target) {

        int sum = accumulate(nums.begin(),nums.end(),0);

        if((sum+target)%2||sum+target<0){

            return 0;

        }

        int dp[(sum+target)/2+1];

        memset(dp,0,sizeof dp);

        dp[0] = 1;

        for(int i = nums.size()-1;i>=0;i--){

            for(int j =(sum+target)/2;j>=0;j--){

                if(j>=nums[i]){

                    dp[j] = dp[j]+dp[j-nums[i]];

                }else{

                    dp[j] = dp[j];

                }

            }

        }

        // return add_pack(nums,0,(sum+target)/2);

        return dp[(sum+target)/2];

    }

};