Target Sum

来源:互联网 发布:网络咨询护士工资多少 编辑:程序博客网 时间:2024/06/05 07:59

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: 5Explanation: -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 = 3There are 5 ways to assign symbols to make the sum of nums be target 3.

简单的可以用递归方法来做,令f(i, s)表示前i个整数目标和为s的方式,则f(i, s)=f(i-1, s+nums[i]) + f(i-1,s-nums[i]). 当i=0时,f(0, s)=0;当i=1, nums[0]=0时,f(1,0)=2;当i=1,s=nums[0]!=0时,f(1,s)=1,否则f(1,s)=0.

也可以用动态规划来做,令A为符号为+的集合,B为符号为-的集合,则

sum(A)-sum(B)=S;

sum(A)-sum(B)+sum(A)+sum(B)=S+sum(A)+sum(B)=S+sum(nums);

2sum(A)=S+sum(nums);

sum(A)=1/2*(S+sum(nums));

现在问题转化为nums[]中有多少种集合A的方式使得A中所有数的和为1/2*(S+sum(nums)).


递归的代码为:

class Solution {public:    int findTargetSumWays(vector<int> nums, int S) {        int size=nums.size();        int temp;        vector<int>::iterator it=nums.begin();        if(size==0)        {            return 0;        }        else if(size==1)        {            if(*it==S&&*it==(-S))            return 2;            else if(*it==S||*it==(-S))            return 1;            else            return 0;        }        else        {            temp=nums[size-1];            nums.erase(it+size-1);            return findTargetSumWays(nums,S-temp)+findTargetSumWays(nums,S+temp);        }    }};







0 0
原创粉丝点击