416 分割等和子集

2021-10-07 22:26:57 字數 1780 閱讀 2492

題目描述:

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

注意:

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

陣列的大小不會超過 200

示例 1:

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

輸出: true

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

示例 2:

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

輸出: false

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

方法1:動態規劃

主要思路:

(1)題目要求陣列的元素能不能組成和相等的兩個集合,則可以先求出整個陣列元素的和,若這個和是奇數,則肯定不能,則直接返回false,若是偶數,則可能能,則除以2得到的sum即為每個集合需要組成的和;

(2)定義 dp[ i ][ j ]表示前 i 個元素能組成的和不超過 j 的最大值,則對於當前的元素 nums[ i-1 ],若其值大於 j,既dp[ i ][ j ]的值只能是 dp[i][j]=dp[i-1][j];,若nums[ i-1 ]的值小於等於 j,則dp[ i][ j ]的值還可能為dp[i-1][j-nums[i-1]]+nums[i-1],故dp[i][j]=max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1]);

(3)若在這個過程中,獲得了dp[i][sum]==sum的情形,則剩餘的其他的元素的和一定也是sum,故可以提前終止,返回false;

class

solution

if(sum%2==

1)return

false

; sum/=2

;//獲得需要組成和

vectorint>>

dp(nums.

size()

+1,vector<

int>

(sum+1,

0));

//遍歷各個元素

for(

int i=

1;i<=nums.

size()

;++i)

else

}//提前終止

if(dp[i]

[sum]

==sum)

return

true;}

return dp[nums.

size()

][sum]

==sum;}}

;

方法2:動態規劃

主要思路:

(1)方法2和上述方法1一致,只不過將動態陣列壓縮為一維的,因為從方法1中可以看出,當前dp[ i ][ j ]之和上一行的前面計算過的內容有關,故可以考慮壓縮陣列;

class

solution

if(sum%2==

1)return

false

; sum/=2

; vector<

int>

dp(sum+1,

0);for

(int elem:nums)

if(dp[sum]

==sum)

//提前終止條件

return

true;}

return dp[sum]

==sum;}}

;

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 判斷所給陣列是否滿足條件,若陣列中任意數字和為總和二分之一 總和必須為偶數 則為true class solution def canpar...