题目:
给定一个非空的正整数数组 nums
,请判断能否将这些数字分成元素和相等的两部分。
示例 :
输入:nums = [1,5,11,5] 输出:true 解释:nums 可以分割成 [1, 5, 5] 和 [11] 。
思路:
01背包的思路,如果没看过的,可以先学学01背包。对于我来说,这道easy题真的太难了。
复杂度:
时间:双重循环O(n^2)。
空间:O(n)。
代码:
public boolean canPartition(int[] nums) {
//要做这题要理清楚01背包理论
//首先要清楚两个子集的各自和刚好是总集合的一半
int sum = 0;
for(int num : nums){
sum += num;
}
int target = sum/2;
// 不能平分肯定错
if(sum%2 == 1) return false;
//再明确dp[i] 表示的是背包的总容量是i,也就是dp[i]就是凑成i的集合
//如dp[3] ={1,2},题目有限定条件,长度最大200,单个不超一百。
int dp[] = new int [10001];
//推公式 dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
//遍历要逆向,因为元素不可以重复放入
for(int i = 0; i< nums.length;++i){
for(int j = target; j >= nums[i];--j){
dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
}
}
if(dp[target] == target) return true;
return false;
}