赞
踩
力扣原题链接
给你一个只包含正整数的非空数组nums
。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
示例 1:
输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5] 和 [11] 。
示例 2:
输入:nums = [1,2,3,5]
输出:false
解释:数组不能分割成两个元素和相等的子集。
提示:
1 <= nums.length <= 200
1 <= nums[i] <= 100
我们定义一个二维的动态规划数组 dp
,其中 dp[i][j]
表示在前 i
个物品中,能否选取一些物品使得它们的总和等于 j
。
在状态转移方程中,我们需要考虑当前物品是否放入背包中的两种情况:
nums[i - 1]
,则 dp[i][j] = dp[i - 1][j]
;nums[i - 1]
,则 dp[i][j] = dp[i - 1][j - nums[i - 1]]
。综合以上两种情况,状态转移方程为:
dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i - 1]]
我们需要对动态规划数组进行初始化,当没有物品或背包容量为0时。
class Solution { public boolean canPartition(int[] nums) { int sum = 0; for(int a : nums){ sum +=a; } if(sum % 2 !=0){ return false; } int t = sum/2; int dp [] = new int[t+1]; for(int i = 0 ;i < nums.length ;i ++){//遍历物品 for (int j =t ; j >=nums[i] ;j--){//遍历背包 ! 倒序! dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);//背包最大价值的递推公式 } } if(dp[t] == t ){//判断背包是否装满 return true; }else{ return false; } } }
通过以上步骤,我们可以分析出解决该问题的关键步骤,并用动态规划的思想进行解决。首先计算数组的总和,然后判断是否为偶数,如果不是偶数则返回false。接着根据动态规划的思想初始化dp数组,然后按照状态转移方程进行状态转移,最终返回dp数组的最后一个值。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。