分割等和子集
阿新 • • 發佈:2020-10-11
給定一個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。
注意:
每個陣列中的元素不會超過 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的選法(都不進行選擇)。