成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

leetcode494. Target Sum

RobinTang / 1677人閱讀

摘要:為了尋找合適的正負(fù)號賦值,我們其實(shí)可以將數(shù)組分為兩個(gè)子集,其中一個(gè)子集中的數(shù)字都被賦予了正號,而另一個(gè)子集中的數(shù)字都被賦予了負(fù)號。如果二者的和不是一個(gè)偶數(shù),就一定無法找到這樣的正負(fù)號集合使得其結(jié)果為。

題目要求
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:
The length of the given array is positive and will not exceed 20.
The sum of elements in the given array will not exceed 1000.
Your output answer is guaranteed to be fitted in a 32-bit integer.

現(xiàn)在有一個(gè)整數(shù)數(shù)組,你需要為每一個(gè)數(shù)組賦予正號或是負(fù)號,使其的和為目標(biāo)值。

思路一:廣度優(yōu)先遍歷

直觀的來說,我們可以將所有的情況都嘗試一遍并且將可能構(gòu)成結(jié)果的集合統(tǒng)計(jì)下來。就以題目中例子來說,原始的輸入為[1,1,1,1,1],目標(biāo)值為3。那么我們假設(shè)先給第一個(gè)值設(shè)置為正數(shù),則只需要知道[1,1,1,1]組合成目標(biāo)值2的集合個(gè)數(shù)即可。通過不斷的遞歸調(diào)用,當(dāng)遍歷到數(shù)組的盡頭時(shí),我們只需要知道當(dāng)前的目標(biāo)值是否為0,如果為0,說明該嘗試成功并返回1,否則返回0。

    public int findTargetSumWays(int[] nums, int S) {
        return findTargetSumWays(nums, 0, S);
    }
    
    public int findTargetSumWays(int[] nums, int start, int S){
        if(start==nums.length){
            if(S == 0){
                return 1;
            }else{
                return 0;
            }
        }
        int count = 0;
        count += findTargetSumWays(nums, start+1, S-nums[start+1]);
        count += findTargetSumWays(nums, start+1, S+nums[start+1]);
        return count;
        
    }
思路二:子集查找

這個(gè)是我從網(wǎng)上找來的思路,但是網(wǎng)上的很多博客解釋的并不清楚,這里我再試著詳細(xì)的解釋一下。

為了尋找合適的正負(fù)號賦值,我們其實(shí)可以將數(shù)組分為兩個(gè)子集,其中一個(gè)子集中的數(shù)字都被賦予了正號,而另一個(gè)子集中的數(shù)字都被賦予了負(fù)號。所有的數(shù)字都將落入這兩個(gè)集合中。那么我們令正號的集合為S(P),負(fù)號的集合為S(N),所有數(shù)字的和為sum,目標(biāo)值為target。我們可以推倒出如下結(jié)論:

S(P) + S(N) = sum
S(P) - S(N) = target
S(P) * 2 = sum + target

因此,sum和target的和一定是一個(gè)偶數(shù)。如果二者的和不是一個(gè)偶數(shù),就一定無法找到這樣的正負(fù)號集合使得其結(jié)果為target。

因此,題目被我們轉(zhuǎn)化為從該集合中找到所有子集,每個(gè)子集需滿足其下所有數(shù)字的和為positive = (sum+target)/2。

這個(gè)問題我們可以通過動(dòng)態(tài)規(guī)劃來解決。

假設(shè)我們想知道構(gòu)成positive的集合有多少個(gè),其實(shí)可以分解為以下幾個(gè)部分:

第一步,當(dāng){nums[0],nums[1]}為基數(shù)時(shí),則

Count(positive) = Count(positive-nums[0])
Count(positive-1) = Count(positive-1-nums[0])
...
Count(nums[0]+1) = Count(0)

第二步,當(dāng){nums[0],nums[1]}為基數(shù)時(shí),同理

Count(positive) = Count(positive-nums[0])
Count(positive-1) = Count(positive-1-nums[0])
...
Count(nums[0]+1) = Count(0)

你會(huì)發(fā)現(xiàn)二者的步驟居然是一樣的!因?yàn)檫@里采用了動(dòng)態(tài)規(guī)劃的思想,第一圈遍歷之后,Count(i)上的值實(shí)際上代表著由{nums[0]}為基數(shù)和為i的集合的數(shù)量。第二圈遍歷之后,Count(i)上的值代表著由{nums[0],nums[1]}為基數(shù)時(shí)和為i的集合的數(shù)量。

因此,第n全遍歷后,Count(positive)上的值就代表著由{nums[0], nums[1]...nums[n-1]}為基數(shù)時(shí)和為positive的集合的數(shù)量。

    public int findTargetSumWays2(int[] nums, int S) {
        int sum = 0;
        for(int i = 0; i < nums.length; i++) {
            sum += Math.abs(nums[i]);
        }
        //數(shù)組中所有的值的和小于標(biāo)準(zhǔn)值 或是奇偶性不同 則直接返回
        return  sum < S || (sum + S) % 2 == 1 ? 0 : helper(nums, (sum + S) / 2);
    }
    private int helper(int[] nums, int sum) {
        //array[i]是指和為i的集合有多少個(gè)
        int[] array = new int[sum + 1];
        array[0] = 1;
        for(int i = 0; i < nums.length; i++) {
            for(int j = sum; j - nums[i] >= 0; j--) {
                array[j] += array[j - nums[i]];
            }
        }
        return array[sum];
    }


想要了解更多開發(fā)技術(shù),面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關(guān)注我的微信公眾號!將會(huì)不定期的發(fā)放福利哦~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68667.html

相關(guān)文章

  • Leetcode 相似題只有題號不含代碼。

    找出string里的單詞。 186. Reverse Words in a String II, 434. Number of Segments in a String combination類型題 77. Combinations 39. Combination Sum 40. Combination Sum II 216. Combination Sum III 494. Target S...

    StonePanda 評論0 收藏0
  • Leetcode 題解 - 雙指針

    摘要:一有序數(shù)組的題目描述在有序數(shù)組中找出兩個(gè)數(shù),使它們的和為。解題思路使用雙指針,一個(gè)指針指向值較小的元素,一個(gè)指針指向值較大的元素。輸出二兩數(shù)平方和判斷一個(gè)數(shù)是否為數(shù)平方和開平方根 一、有序數(shù)組的 Two Sum Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1, index2=2 題目描述:在有序數(shù)組中找出兩個(gè)數(shù),使它們...

    leanxi 評論0 收藏0
  • [LeetCode] 416. Partition Equal Subset Sum

    Problem Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. Note:Each of the array ...

    makeFoxPlay 評論0 收藏0
  • leetcode14 4sum

    摘要:這里需要注意及時(shí)處理掉重復(fù)的情況。那么就需要盡可能排除不可能的情況來提高計(jì)算效率。因?yàn)閿?shù)組已經(jīng)被排序,所以可以根據(jù)數(shù)組中元素的位置判斷接下來的情況是否有可能合成目標(biāo)值。 題目要求 此處為原題地址 Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d =...

    MoAir 評論0 收藏0
  • leetcode40 combination sum 2

    摘要:參考思路和非常類似,只是這里需要增加進(jìn)行重復(fù)處理的部分。題目要求題目中新添的要求包括數(shù)組中存在重復(fù)值,而且數(shù)組中每個(gè)值只可以使用一次。需要注意的是,既然數(shù)組中存在重復(fù)的值,就要注意可能會(huì)將重復(fù)的情況加入結(jié)果數(shù)組。 參考 思路和leetcode39 combination sum 非常類似,只是這里需要增加進(jìn)行重復(fù)處理的部分。請參考我對leetcode39進(jìn)行解答的這篇博客。 題目要求 ...

    Code4App 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<