给定一个只包含正整数的非空数组。是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
注意:
- 每个数组中的元素不会超过 100
 
- 数组的大小不会超过 200
 
示例 1:
1 2 3 4 5
   | 输入: [1, 5, 11, 5]
  输出: true
  解释: 数组可以分割成 [1, 5, 5] 和 [11].
   | 
 
示例 2:
1 2 3 4 5
   | 输入: [1, 2, 3, 5]
  输出: false
  解释: 数组不能分割成两个元素和相等的子集.
   | 
 
思路
1 2 3 4 5 6 7 8
   | 0-1 背包问题:
  首先计算出dp[0][w]  w:0 ~ target-1; 之后计算出dp[i][0]  i:0 ~ 数组len-1;
  case 1 :vi == j+1   dp[i][j]=true; case 2 :vi >j+1 	dp[i][j]=dp[i-1][j]; case 3 :vi <j+1		dp[i][j]=dp[i-1][j] || dp[i-1][j-vi];
   | 
 
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
   | class Solution {     public boolean canPartition(int[] nums) {         int len = nums.length;         int total=0;         for(int i =0;i<len;i++){             total+=nums[i];         }         if(total%2==1){             return false;         }         int y=total/2;         boolean[][] dp = new boolean[len][y];         int temp =nums[0];         for(int i =0;i<y;i++){             dp[0][i]=(temp==(i+1));         }         boolean containOne=false;         for(int i =0;i<len;i++){             if(containOne){             }else{                if(nums[i]==1){                    containOne=true;                }              }             dp[i][0]=containOne;         }         for(int i=1;i<len;i++){             int vi = nums[i];             for(int j=1;j<y;j++){                 if(vi==(j+1)){                     dp[i][j]=true;                   }else if(vi > (j+1)){                     dp[i][j]=dp[i-1][j];                 }else{                     dp[i][j]=dp[i-1][j]||dp[i-1][j-vi];                 }             }         }         return dp[len-1][y-1];     } }
  |