Advertisement
1988coder

416. Partition Equal Subset Sum

Jan 3rd, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 3.04 KB | None | 0 0
  1. /**
  2.  * Dynamic Programming (2D Array). See below solution for 1D array DP.
  3.  *
  4.  * Actually, this is a 0/1 knapsack problem, for each number, we can pick it or
  5.  * not.
  6.  *
  7.  * Let us assume dp[i][s] means whether the specific sum s can be gotten from
  8.  * the first i numbers. If we can pick such a series of numbers from 0-i whose
  9.  * sum is S, dp[i][s] is true, otherwise it is false.
  10.  *
  11.  * Base case: dp[0][0] is true; (zero number consists of sum 0 is true)
  12.  *
  13.  * Transition function: For each number, if we don't pick it, dp[i][s] =
  14.  * dp[i-1][s], which means if the first i-1 elements has made it to s, dp[i][s]
  15.  * would also make it to s (we can just ignore nums[i]). If we pick nums[i].
  16.  * dp[i][s] = dp[i-1][s-nums[i]], which represents that s is composed of the
  17.  * current value nums[i] and the remaining composed of other previous numbers.
  18.  * Thus, the transition function is dp[i][s] = dp[i-1][s] || dp[i-1][s-nums[i]]
  19.  *
  20.  * Time Complexity: O(N * S)
  21.  *
  22.  * Space Complexity: O(N * S)
  23.  *
  24.  * N = Length of the input array. S = Sum of all elements of the input array.
  25.  */
  26. class Solution {
  27.     public boolean canPartition(int[] nums) {
  28.         if (nums == null) {
  29.             return false;
  30.         }
  31.         // Empty array can be divided in two empty subsets.
  32.         if (nums.length == 0) {
  33.             return true;
  34.         }
  35.  
  36.         int sum = 0;
  37.         for (int num : nums) {
  38.             sum += num;
  39.         }
  40.         if ((sum & 1) == 1) {
  41.             return false;
  42.         }
  43.         sum /= 2;
  44.  
  45.         boolean[][] dp = new boolean[nums.length + 1][sum + 1];
  46.         dp[0][0] = true;
  47.  
  48.         for (int i = 1; i <= nums.length; i++) {
  49.             dp[i][0] = true;
  50.             for (int s = 1; s <= sum; s++) {
  51.                 if (s >= nums[i - 1]) {
  52.                     dp[i][s] = dp[i - 1][s] || dp[i - 1][s - nums[i - 1]];
  53.                 } else {
  54.                     dp[i][s] = dp[i - 1][s];
  55.                 }
  56.             }
  57.         }
  58.         return dp[nums.length][sum];
  59.     }
  60. }
  61.  
  62. /**
  63.  * Dynamic Programming Using 1D array.
  64.  *
  65.  * Explaination of the logic refer to comments of previous solution.
  66.  *
  67.  * Time Complexity: O(N * S)
  68.  *
  69.  * Space Complexity: O(S)
  70.  *
  71.  * N = Length of the input array. S = Sum of all elements of the input array.
  72.  */
  73. class Solution {
  74.     public boolean canPartition(int[] nums) {
  75.         if (nums == null) {
  76.             return false;
  77.         }
  78.         // Empty array can be divided in two empty subsets.
  79.         if (nums.length == 0) {
  80.             return true;
  81.         }
  82.  
  83.         int sum = 0;
  84.         for (int num : nums) {
  85.             sum += num;
  86.         }
  87.         if ((sum & 1) == 1) {
  88.             return false;
  89.         }
  90.         sum /= 2;
  91.  
  92.         boolean[] dp = new boolean[sum + 1];
  93.         dp[0] = true;
  94.  
  95.         for (int num : nums) {
  96.             for (int s = sum; s >= num; s--) {
  97.                 dp[s] = dp[s] || dp[s - num];
  98.                 if (s == sum && dp[s]) {
  99.                     return true;
  100.                 }
  101.             }
  102.         }
  103.         return dp[sum];
  104.     }
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement