494. Target Sum Medium

先給出一個遞歸的解法。主要思想:一組數,每個數會有 + 和 - 兩種選擇,那我們可以利用遞歸來遍歷求解所有的情況,n個數,就有2^n種情況,實際上是一個二叉樹,每個節點有兩種選擇。實現起來很簡單,但是效率比較差,畢竟有些情況明顯不可取,還是要遍歷。

class Solution {
public:
	int count;
    int findTargetSumWays(vector<int>& nums, int S) {
        count = 0;
        f(nums, 0, 0, S);
        return count;
    }
    void f(vector<int>& nums, int index, int sum, int s)
    {
    	if(index == nums.size()){
    		if(sum == s)count++;
    	} 
    	else {
    		f(nums, index + 1, sum + nums[index], s);
    		f(nums, index + 1, sum - nums[index], s);
    	}
    }
};

下面是動態規劃的方法。

第一種思路,通過某種奇妙的運算,把問題轉化成:求數組中取數,使和爲(target + 數組的和)/ 2 的方案數。

這就變成416這道題。代碼如下:

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int S) {
    	int target = 0;
        for(int i = 0; i < nums.size(); i++)
        	target += nums[i];
        if((target + S)%2 == 1 || target < S)return 0;
        target = (target + S) >> 1;
        
        int d[target + 1] = {0};
        d[0] = 1;
        
        for (int i = 0; i < nums.size(); ++i)
        {
        	for (int j = target; j >= nums[i]; --j){
        		d[j] += d[j - nums[i]]; 
        	}
        }
        return d[target];
    }
};
第二種思想:每個數有加正號和符號兩種選擇,那就類似揹包問題。方程:d[i][j] = d[i - 1][j + num[i - 1]] + d[i-1][j - num[i - 1]]。 表示前i個數添加符號後結果爲j的方案數。需要注意的是,矩陣是比num.size()+1行,S+1列要大

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章