Leetcode題解系列——416. Partition Equal Subset Sum(c++版)
阿新 • • 發佈:2018-12-16
題目連結:416. Partition Equal Subset Sum
題目大意:題目給出一個數組,分割成兩個集合,判斷這兩個集合的和相等。
一.演算法設計
這是一道經典的動態規劃問題,判斷子集合的和是否相等,由於集合的組成需要指數的構造時間,不符合題目要求的時間複雜度。這道演算法題可以類比成揹包問題。
既然要劃分成兩個集合的和都相等,那麼我們先算出這個集合的總和,這個sum必須為偶數,才能劃分成功
然後,這個sum的一半就是我們所要達到的目標。為什麼說它像揹包問題呢,因為這個sum的一半可以比作揹包的容量w,我們想利用陣列中的元素恰好填滿這個w容量的揹包,且其中的元素不能重複有且只有一個。
因此我們可以寫出狀態轉移方程
dp[i] = dp[i] || dp[i-num]
其中dp[i]表達的是選取陣列的元素,是否可以恰好填滿容量i的揹包。 若dp為1,則證明可以填充;dp為0則不能。
最後,我們只需要判斷dp[target]是否為1即可,判斷是否存在這樣的劃分。
注意點:
- 這裡的遍歷要求第一層遍歷nums陣列中的元素,第二層要從target值開始從後到前這樣來遍歷,避免陣列越界的情況。
二.演算法實現
class Solution {
public:
bool canPartition(vector<int> & nums) {
int sum = accumulate(nums.begin(), nums.end(), 0);
if(sum%2 != 0) return false;
int target = sum / 2;
vector<int> dp(target+1,0);
dp[0] = 1;
for(int num : nums){
for(int i = target; i >= num ; i--){
dp[ i] = dp[i] || dp[i-num];
}
}
return dp[target];
}
};