动态规划解法:
1.分割等和子集,总数为偶数能分成两个等和子集,总数为奇数一定不能分割成两个等和子集
2. 定义一个二维数组来表示在0-len的物品中凑齐sum/2的背包容量
3.初始化第0行中刚好能凑齐背包的容量并赋值给相应的dp数组
4.遍历物品和背包容量来递推完善dp数组,检查dp数组的最后一个位置是否凑齐了sum/2的背包容量。
class Solution {
public boolean canPartition(int[] nums) {
int len=nums.length;
int sum=0;
//将全部的值相加起来算总值
for (int i:nums){
sum+=i;
}
//如果是奇数,总数不能平分返回false
if(sum%2==1){
return false;
}
//定义一个二维数组来表示在0-len中凑齐sum/2的背包容量
int [][] dp=new int [len][sum/2+1];
//初始化第0行中刚好能凑齐背包的容量并赋值给相应的dp数组
for (int i=1;i<=sum/2;i++){
if(nums[0]==i){
dp[0][i]=i;
}
}
//先遍历物品
for (int i=1;i<len;i++){
//在遍历背包容量
for (int j=1;j<=sum/2;j++){
// 先把上一层在0到i-1物品中凑齐j背包容量赋值给dp【i】【j】
dp[i][j] = dp[i-1][j];
//在进行的更新,防止num【i】>大于j容量,造成数组下标越界
if(nums[i]<j){
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
}
}
}
//判断dp【len-1】【sum/2】的值是否凑齐了sum/2
if(dp[len-1][sum/2]==sum/2){
return true;
}
return false;
}
}