1. 程式人生 > 實用技巧 >分割等和子集

分割等和子集

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

注意:

每個陣列中的元素不會超過 100
陣列的大小不會超過 200
示例 1:

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

輸出: true

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

示例2:

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

輸出: false

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

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int n = nums.size();
        
if(n < 2){ return false; } int sum = 0,maxNum = 0; for(auto& num:nums){ sum += num; maxNum = max(maxNum,num); } if(sum &1){ return false;//是奇數的話說明不能被分割成兩個子集 } int target = sum /2; if
(maxNum > target){ return false;//如果最大的數超過總和的一半,說明也不能被分割成兩個子集 } vector<int> dp(target+1,0);//需要採用動態規劃的方式去求解,以空間換時間。 //如果直接採用深度搜索的方式會超時 //空間壓縮,注意範圍的限制 dp[0] = true; for(int i=0;i<n;++i){ int num = nums[i]; for(int j=target;j>=num;--j){ dp[j]
|= dp[j-num]; } } return dp[target]; } };

//注意:

1.很大一部分求目標和的問題都可以轉換成動態規劃問題(注意目標和是否有上界,有上界提示的話則可以考慮用空間換時間使用動態規劃)。

2.壓縮空間後,第二重迴圈採用倒敘的方式。

3.注意初始條件dp[i][0]為true,壓縮空間後是dp[0]為true,即為存在實現和為0的選法(都不進行選擇)。