看到这个我们第一步要想到是,这是一个01背包问题
本质上就是求是否可以让数相加等于总和的一半
动态规划五部曲
(1)确定dp函数 dp[i][j]表示第i个数能否和前面的数(或自己单独)凑成j
(2)确定递归公式 如果不考虑nums[i] nums[i][j] = nums[i-1][j];
如果考虑nums[i] nums[i][j] = nums[ i-1 ] [ j-nums[i] ]
(3)dp数组如何初始化 初始化目标对准第一行和第一列
(4)确定遍历顺序 先便利数组的数字,再遍历纵坐标
(5)列举推导
class Solution {
public boolean canPartition(int[] nums) {
int sum = 0;
for(int num:nums){
sum +=num;
}
if(sum%2!=0){
return false;
}
int target = sum/2;
boolean[][] dp=new boolean[nums.length][target+1];
for(int i = 0;i<nums.length;i++){
dp[i][0]=false;
}
if(nums[0]<=target){
dp[0][nums[0]]=true;
}
for(int i=1;i<nums.length;i++){
for(int j =0;j<=target;j++){
dp[i][j] = dp[i-1][j];
if(nums[i]==j){
dp[i][j]=true;
continue;
}
if(nums[i]<j){
dp[i][j]=dp[i-1][j-nums[i]]||dp[i-1][j];
}
}
}
return dp[nums.length-1][target];
}
}