1. 程式人生 > 其它 >【刷題】494. 目標和

【刷題】494. 目標和

參考:494. 目標和

輸入:nums = [1,1,1,1,1], target = 3
輸出:5
解釋:一共有 5 種方法讓最終目標和為 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
+1 + 1 + 1 + 1 - 1 = 3

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/target-sum
著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。

筆記:

  1. 假如加法總和是left,減法總和是right(sum-left),所求是target,那麼有以下關係式:left-(sum-left)=target,sumtarget已知,那麼left-sum+left=target,即left=(sum+target)/2。 此時問題就轉化為,裝滿容量為x揹包,有幾種方法。
  2. 【1】dp[i]含義:dp[j] 表示:填滿j(包括j)這麼大容積的包,有dp[i]種方法其實也可以使用二維dp陣列來求解本題,dp[i][j]:使用 下標為[0, i]的nums[i]能夠湊滿j(包括j)這麼大容量的包,有dp[i][j]種方法。 【2】確定遞推公式:有哪些來源可以推出dp[j]呢? 不考慮nums[i]的情況下,填滿容量為j - nums[i]的揹包,有dp[j - nums[i]]種方法。 那麼只要搞到nums[i]的話,湊成dp[j]就有dp[j - nums[i]] 種方法。 舉一個例子,nums[i] = 2: dp[3],填滿揹包容量為3的話,有dp[3]種方法。 那麼只需要搞到一個2(nums[i]),有dp[3]方法可以湊齊容量為3的揹包,相應的就有多少種方法可以湊齊容量為5的揹包。 那麼需要把 這些方法累加起來就可以了,dp[j] += dp[j - nums[i]]

    【3】 dp陣列如何初始化。從遞迴公式可以看出,在初始化的時候dp[0] 一定要初始化為1,因為dp[0]是在公式中一切遞推結果的起源,如果dp[0]是0的話,遞迴結果將都是0。 dp[0] = 1,理論上也很好解釋,裝滿容量為0的揹包,有1種方法,就是裝0件物品。 dp[j]其他下標對應的數值應該初始化為0,從遞迴公式也可以看出,dp[j]要保證是0的初始值,才能正確的由dp[j - nums[i]]推匯出來。 【4】確定遍歷順序 在動態規劃:關於01揹包問題,你該瞭解這些!(滾動陣列) (opens new window)中,我們講過對於01揹包問題一維dp的遍歷,nums放在外迴圈,target在內迴圈,且內迴圈倒序。【5】

    舉例推導dp陣列 輸入:nums: [1, 1, 1, 1, 1], S: 3 bagSize = (S + sum) / 2 = (3 + 5) / 2 = 4 dp陣列狀態變化如下:(最好手動推敲一下)

  3. 上圖記得從下標4開始看,因為是倒序遍歷。