LeetCodee

416. Partition Equal Subset Sum

Jump to Solution: Python Java C++ JavaScript C#

Problem Description

Given an integer array nums, return true if you can partition the array into two subsets such that the sum of the elements in both subsets is equal or false otherwise.

Example 1:

Input: nums = [1,5,11,5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].

Example 2:

Input: nums = [1,2,3,5]
Output: false
Explanation: The array cannot be partitioned into equal sum subsets.

Constraints:

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 100

Solution

Python Solution

class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        total_sum = sum(nums)
        
        # If total sum is odd, we can't partition into equal subsets
        if total_sum % 2 != 0:
            return False
        
        target = total_sum // 2
        dp = set([0])
        
        # For each number, check if we can make any new sums
        for num in nums:
            # We need to create a new set to avoid modifying while iterating
            next_dp = dp.copy()
            for curr_sum in dp:
                next_sum = curr_sum + num
                if next_sum == target:
                    return True
                if next_sum < target:
                    next_dp.add(next_sum)
            dp = next_dp
        
        return False

Time Complexity: O(n * sum)

Where n is the length of nums and sum is the total sum of all numbers.

Space Complexity: O(sum)

For storing all possible sums in the dp set.

Java Solution

class Solution {
    public boolean canPartition(int[] nums) {
        int totalSum = 0;
        for (int num : nums) {
            totalSum += num;
        }
        
        // If total sum is odd, we can't partition into equal subsets
        if (totalSum % 2 != 0) {
            return false;
        }
        
        int target = totalSum / 2;
        boolean[] dp = new boolean[target + 1];
        dp[0] = true;
        
        // For each number, check if we can make any new sums
        for (int num : nums) {
            for (int i = target; i >= num; i--) {
                dp[i] = dp[i] || dp[i - num];
            }
        }
        
        return dp[target];
    }
}

Time Complexity: O(n * sum)

Where n is the length of nums and sum is the total sum of all numbers.

Space Complexity: O(sum)

For storing the dp array.

C++ Solution

class Solution {
public:
    bool canPartition(vector& nums) {
        int totalSum = accumulate(nums.begin(), nums.end(), 0);
        
        // If total sum is odd, we can't partition into equal subsets
        if (totalSum % 2 != 0) {
            return false;
        }
        
        int target = totalSum / 2;
        vector dp(target + 1, false);
        dp[0] = true;
        
        // For each number, check if we can make any new sums
        for (int num : nums) {
            for (int i = target; i >= num; i--) {
                dp[i] = dp[i] || dp[i - num];
            }
        }
        
        return dp[target];
    }
};

Time Complexity: O(n * sum)

Where n is the length of nums and sum is the total sum of all numbers.

Space Complexity: O(sum)

For storing the dp vector.

JavaScript Solution

/**
 * @param {number[]} nums
 * @return {boolean}
 */
var canPartition = function(nums) {
    const totalSum = nums.reduce((a, b) => a + b, 0);
    
    // If total sum is odd, we can't partition into equal subsets
    if (totalSum % 2 !== 0) {
        return false;
    }
    
    const target = totalSum / 2;
    const dp = new Set([0]);
    
    // For each number, check if we can make any new sums
    for (const num of nums) {
        const nextDp = new Set(dp);
        for (const currSum of dp) {
            const nextSum = currSum + num;
            if (nextSum === target) {
                return true;
            }
            if (nextSum < target) {
                nextDp.add(nextSum);
            }
        }
        dp = nextDp;
    }
    
    return false;
};

Time Complexity: O(n * sum)

Where n is the length of nums and sum is the total sum of all numbers.

Space Complexity: O(sum)

For storing all possible sums in the dp set.

C# Solution

public class Solution {
    public bool CanPartition(int[] nums) {
        int totalSum = nums.Sum();
        
        // If total sum is odd, we can't partition into equal subsets
        if (totalSum % 2 != 0) {
            return false;
        }
        
        int target = totalSum / 2;
        bool[] dp = new bool[target + 1];
        dp[0] = true;
        
        // For each number, check if we can make any new sums
        foreach (int num in nums) {
            for (int i = target; i >= num; i--) {
                dp[i] = dp[i] || dp[i - num];
            }
        }
        
        return dp[target];
    }
}

Time Complexity: O(n * sum)

Where n is the length of nums and sum is the total sum of all numbers.

Space Complexity: O(sum)

For storing the dp array.

Approach Explanation

The solution uses dynamic programming approach:

  1. Key Insights:
    • Sum calculation
    • Subset problem
    • DP optimization
    • State tracking
  2. Algorithm Steps:
    • Check total sum
    • Find target sum
    • Build DP table
    • Track possible sums

Implementation Details:

  • Sum handling
  • State management
  • Memory optimization
  • Early termination

Optimization Insights:

  • Space reduction
  • Early checks
  • Efficient storage
  • Quick validation

Edge Cases:

  • Empty array
  • Single element
  • Odd total sum
  • Large numbers