題目描述:
給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。
注意:
每個陣列中的元素不會超過 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...