L416分割等和子集

2021-10-05 13:26:37 字數 2678 閱讀 5132

分割等和子集

給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。

注意:每個陣列中的元素不會超過 100

陣列的大小不會超過 200

示例 1:

輸入: [1, 5, 11, 5]

輸出: true

解釋: 陣列可以分割成 [1, 5, 5] 和 [11].

示例 2:

輸入: [1, 2, 3, 5]

輸出: false

解釋: 陣列不能分割成兩個元素和相等的子集.

== 以下全是0-1揹包問題的解答模式,從二維降到一維==

要明白為什麼能夠照抄下來,

dp[i][j] = dp[i - 1][j],其實表達的意思並不是恰好滿足,從0-i的所有的數都被使用,而是0-i中某些數字的和滿足該條件,導致dp[i]【j】也是成立的

表示第一種情況,不選擇當前元素dp[i][j] = dp[i - 1][j]

若用一維陣列來表示,即為dp[i] = dp[i]

class

solution

if(sum %2==

1)return

false

;int target = sum /2;

boolean

dp =

newboolean

[len]

[target +1]

;if(nums[0]

<= target) dp[0]

[nums[0]

]=true

;for

(int i=

1; i < len; i++

)else

if(nums[i]

< j)}}

return dp[len -1]

[target];}

}

上面的判斷分支過多,可以合併,這個時候需要將dp[0][0] = true,可以參考

class

solution

if(sum %2==

1)return

false

;int target = sum /2;

boolean

dp =

newboolean

[len]

[target +1]

; dp[0]

[0]=

true

;//這裡先定義,下面就可以合併分支

if(nums[0]

<= target) dp[0]

[nums[0]

]=true

;//先初始化第一行

for(

int i=

1; i < len; i++)}

if(dp[i]

[target]

)return

true

;//這個剪枝,可以提前結束,只要存在乙個就一定滿足

}return dp[len -1]

[target];}

}

壓縮至一維

0-1 揹包問題」常規優化:「狀態陣列」從二維降到一維,減少空間複雜度。

class

solution

if(sum %2==

1)return

false

;int target = sum /2;

boolean

dp =

newboolean

[target +1]

;//壓縮狀態,實際移動的就是j

//因為每一行在更新的時候只是用到其上一行的資料,但是要保證在更新的時候上一行的資料不能被覆蓋

if(nums[0]

<= target) dp[nums[0]

]=true

;//這裡一定要判斷,有可能樣例是超過的,結果就拋異常

dp[0]

=true

;for

(int i=

1; i < len; i++)}

if(dp[target]

)return

true

;//同時還是要剪枝

}return dp[target];}

}

再進一步優化

class

solution

if(sum %2==

1)return

false

;int target = sum /2;

boolean

dp =

newboolean

[target +1]

;//壓縮狀態,實際移動的就是j

//因為每一行在更新的時候只是用到其上一行的資料,但是要保證在更新的時候上一行的資料不能被覆蓋

if(nums[0]

<= target) dp[nums[0]

]=true

;//不要這句也可以,下面i從0開始,只要把dp[0]= true即可

dp[0]

=true

;for

(int i=

1; i < len; i++)}

return dp[target];}

}

416 分割等和子集

給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。注意 每個陣列中的元素不會超過 100 陣列的大小不會超過 200 示例 1 輸入 1,5,11,5 輸出 true 解釋 陣列可以分割成 1,5,5 和 11 示例 2 輸入 1,2,3,5 輸出 fals...

416 分割等和子集

主要題目中說了不超過100個數字,數字都不超過200。所以可能的和不會超過20000,這個量級對計算機來說不算大,所以考慮用dp考察每個可能的和是否存在。class solution int sum accumulate nums.begin nums.end 0 if sum 1 int siz ...

416 分割等和子集

題目描述 給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。注意 每個陣列中的元素不會超過 100 陣列的大小不會超過 200 示例 1 輸入 1,5,11,5 輸出 true 解釋 陣列可以分割成 1,5,5 和 11 示例 2 輸入 1,2,3,5 輸出...