1. 程式人生 > >Leetcode題解系列——416. Partition Equal Subset Sum(c++版)

Leetcode題解系列——416. Partition Equal Subset Sum(c++版)

題目連結: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即可,判斷是否存在這樣的劃分。

注意點:

  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]; } };