1. 程式人生 > >[LeetCode] Target Sum通過新增+/-獲得目標結果

[LeetCode] Target Sum通過新增+/-獲得目標結果

宣告:原題目轉載自LeetCode,解答部分為原創

 Problem :

        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: 5
Explanation: 

-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

There are 5 ways to assign symbols to make the sum of nums be target 3.

Note:

  1. The length of the given array is positive and will not exceed 20.
  2. The sum of elements in the given array will not exceed 1000.
  3. Your output answer is guaranteed to be fitted in a 32-bit integer.
Solution:

        思路:動態規劃型別。通過給陣列的每個數值新增+/-符號,可以將陣列分為兩個部分,分別是正陣列pos[ ]和負陣列neg[ ],目標結果為:

        target = sum_of_pos - sum_of_neg

target = sum_of_pos - (sum_of_array - sum_of_pos)

target = 2 * sum_of_pos - sum_of_array

        通過以上推導,我們可以將題意轉化成我們比較熟悉的型別,即求解和為某定值的子集的個數。在本題中,對應的目標和指的是sum_of_pos。

求解和為某定值的子集的個數,詳見另一篇文章“[LeetCode] Partition Equal Subset Sum劃分陣列形成兩個和相等的子集”。

        程式碼如下:

#include<iostream>
#include<vector>
using namespace std;

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int s) {
        int sum = 0;
		for(int i = 0 ; i < nums.size() ; i ++)
		{
			sum += nums[i];
		}
		
		if(sum < s)
			return 0;
		else if((sum + s) % 2 != 0)
			return 0;
		else
			return count(nums, (sum + s) / 2);
    }

    int count(vector<int>& nums, int target) {
    	if(nums.size() == 0)
    		return 0;
    	
    	vector<int> count_of_sum(target + 1, 0);
    	count_of_sum[0] = 1;
    	for(int i = 0 ; i < nums.size() ; i++)
    	{
    		int add = nums[i];
    		for(int j = target; j >= add; j --)
    		{
    			count_of_sum[j] += count_of_sum[j - add];
			}
		}
		
		return count_of_sum[target];
    }
};

int main()
{
	Solution text;
	vector<int> nums(8,1);
	cout << text.findTargetSumWays(nums, 4) << endl;
	return 0;
}