思路
回溯会超时,必须动态规划。
此时 数组长度为物品数量,数组大小为物品重量与价值,目标是
当背包大小为 sum/2时,背包的价值总量正好也是sum/2
一维dp
var canPartition = function(nums) {
const sum =nums.reduce((x,y)=>x +y)
if(sum%2 !=0) return false //无法平分
let dp =new Array(sum/2 +1).fill(0)
// 物品个数
for(let i=0;i<nums.length;i++){
for(let j=sum/2;j>=nums[i];j--){
//背包重量递减
dp[j] =Math.max(dp[j],(dp[j-nums[i]]+nums[i]))
if(dp[j]===sum/2) return true
}
}
return dp[sum/2]===sum/2
};
二维dp
var canPartition = function(nums) {
const sum =nums.reduce((x,y)=>x +y)
if(sum%2 !=0) return false //无法平分
let dp =new Array(nums.length+1).fill(0).map(()=> new Array(sum/2 +1).fill(0))
// 第一个数只填充大于等于它的那个背包格子
for(let i=nums[0];i<sum/2;i++){
if(i<=sum/2){
dp[0][i] =nums[0]
}
}
// 物品个数
for(let i=1;i<=nums.length;i++){
for(let j=0;j<=sum/2;j++){
if(j>=nums[i]){
dp[i][j] =Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i])
}else{
dp[i][j] =dp[i-1][j]
}
}
}
return dp[nums.length][sum/2]===sum/2
};