leetcode 494 目標和(DP 動態規劃)

2021-10-04 01:46:16 字數 2496 閱讀 2024

給定乙個非負整數陣列,a1, a2, …, an, 和乙個目標數,s。現在你有兩個符號 + 和 -。對於陣列中的任意乙個整數,你都可以從 + 或 -中選擇乙個符號新增在前面。

返回可以使最終陣列和為目標數 s 的所有新增符號的方法數。

本題是典型的「動態規劃」問題。設陣列的長度為n,

當陣列的前n-1項(nums[0]到nums[n-2])按照題中的要求得出了s-nums[n-1],則最後「+nums[n-1]」就滿足了題中要求,方法數加1。

或者陣列的前n-1項(nums[0]到nums[n-2])按照題中的要求得出了s+nums[n-1],則最後「-nums[n-1]」也滿足了題中要求,方法數加1。

dp()findtargetsumways()的意義相同,vectortemp為當前vectornums除最後一項外剩下的元素組成的陣列、lennums的長度。

所以可以得出「狀態轉移公式」:dp(

nums

,s)=

dp(t

emp,

s−nu

ms[l

en−1

])+d

p(te

mp,s

+num

s[le

n−1]

)dp(nums,s) = dp(temp,s-nums[len-1])+dp(temp, s+nums[len-1])

dp(num

s,s)

=dp(

temp

,s−n

ums[

len−

1])+

dp(t

emp,

s+nu

ms[l

en−1

])普通的動態規劃遞迴函式會超時,在這裡不再說明。接下來用題中的「示例1」來說明使用「二維陣列」來解題的方法。

**中橫座標表示從前到後掃瞄陣列,當前掃瞄到的陣列元素。縱座標表示的是此時的目標數。對應的**內容則是對應的方法數。

如**中的(nums[2] = 1,-1)= 3表示的是掃瞄到陣列的第三個元素時,組合得到目標數s = -3的方法有3種。

從**種能夠得到(nums[4] = 1,3)= 5!

並且**中-s和s對應的方法數是相同的,這樣可以進一步縮短「二維陣列」的規模。

構造陣列:

初始化二維陣列的所有元素都為「0」。把第一行中與陣列第乙個元素相等的列數對應的**置為「1」。(這裡要注意的是,原本也要標記-s的情況,由於上述的原因而省略了,但如果s = 0,則-s = s,對應的位置就要標記兩次)

接下來從第一行開始迴圈,掃瞄每乙個元素,掃瞄到(i,

j)(i,j)

(i,j

)是非零元素時,其(i+

1,j±

nums

[i+1

]的絕對

值)(i+1,j\pm nums[i+1]的絕對值)

(i+1,j

±num

s[i+

1]的絕

對值)要加上(i,

j)(i,j)

(i,j

)對應的值。(掃瞄每一行之後別忘了把s=0對應的**元素本身×

最後一行,s的絕對值列對應的**元素就是本題要求的方法數

class

solution

int dp[20]

[1001];

int len = nums.

size()

;// 初始化dp陣列

memset

(dp,0,

sizeof

(dp));

dp[0]

[nums[0]

]=1;

dp[0]

[0]*

=2;for

(int i =

0; i < len -

1; i++

) dp[i +1]

[j + nums[i +1]

]+= dp[i]

[j];}}

// 每一行之後別忘了把s=0對應的**元素本身*2

dp[i +1]

[0]*

=2;}

return dp[len -1]

[abs

(s)];}

};

發現問題歡迎指出和糾正,謝謝!

leetcode 494目標和 揹包dp

class solution def findtargetsumways self,nums,s int dp i j means solutionnums n len nums sum max sum nums sum min sum max dp dp 0for in range s 1 for...

0 1揹包 LeetCode 494 目標和

494.目標和 給定乙個非負整數陣列,a1,a2,an,和乙個目標數,s。現在你有兩個符號 和 對於陣列中的任意乙個整數,你都可以從 或 中選擇乙個符號新增在前面。返回可以使最終陣列和為目標數 s 的所有新增符號的方法數。示例 1 輸入 nums 1,1,1,1,1 s 3 輸出 5 解釋 1 1 ...

494 目標和 力扣

題意理解 給定一陣列,在每個數前增加 符號構成表示式,求和等於s的數量。問題分析 動規狀態量是前i個數字,和等於j的數量。狀態轉移方程是前i個數字,和等於j的數量等於前i 1個數字,和等於j 當前數字的數量 前i 1個數字,和等於j 當前數字的數量。其他鏈結 int findtargetsumway...