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
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
We're trying to see if a collection of numbers can be split into two groups that have the same total. The brute force way is to just try every possible combination of numbers in each group. We create all the possible groups and compare the sums.
Here's how the algorithm would work step-by-step:
def can_partition_equal_subset_sum_brute_force(numbers):
total_sum = sum(numbers)
# If the total sum is odd, it cannot be partitioned
if total_sum % 2 != 0:
return False
target_sum = total_sum // 2
def find_subset(index, current_subset_sum):
# If we've reached the end of the list
if index == len(numbers):
return current_subset_sum == target_sum
# Check if including the current number leads to a solution
if find_subset(index + 1, current_subset_sum + numbers[index]):
return True
# Check if excluding the current number leads to a solution
if find_subset(index + 1, current_subset_sum):
return True
return False
# Start the recursive search for a subset
return find_subset(0, 0)
The problem asks whether we can divide a collection of numbers into two groups that have the same sum. Instead of checking every possible split, we use a trick to see if a solution is even possible and then use a strategy to build one of the groups.
Here's how the algorithm would work step-by-step:
def can_partition(numbers): total_sum = sum(numbers)
if total_sum % 2 != 0:
return False
target_sum = total_sum // 2
number_of_numbers = len(numbers)
# Create a DP table to store results of subproblems
dp_table = [[False for _ in range(target_sum + 1)] for _ in range(number_of_numbers + 1)]
# Initialize the first column to True, as a sum of 0 is always possible.
for i in range(number_of_numbers + 1):
dp_table[i][0] = True
for i in range(1, number_of_numbers + 1):
for j in range(1, target_sum + 1):
# If current number is greater than the current sum, exclude it
if numbers[i - 1] > j:
dp_table[i][j] = dp_table[i - 1][j]
else:
# Decide whether to include the current number or not
dp_table[i][j] = dp_table[i - 1][j] or dp_table[i - 1][j - numbers[i - 1]]
# The result is stored in the bottom-right corner of the DP table
return dp_table[number_of_numbers][target_sum]
Case | How to Handle |
---|---|
Empty input array (nums is null or nums.length == 0) | Return false immediately as an empty set cannot be partitioned into two equal subsets. |
Array with only one element | Return false immediately because one element cannot be partitioned into two equal subsets unless the element is 0, which also should return false. |
Sum of elements is odd (target sum is not an integer) | Return false immediately because if the sum is odd, it's impossible to divide it into two equal integer subsets. |
Array contains negative numbers | The standard dynamic programming approach doesn't directly handle negative numbers, requiring a transformation or adjustment to shift all numbers to non-negative. |
Array contains zero(s) | Zeros should not affect the correctness of the dynamic programming solution, but could cause inefficiencies in some approaches like recursion if not handled carefully. |
Very large numbers or a very large sum leading to integer overflow | Use a larger data type (e.g., long) or modular arithmetic during sum calculations to prevent integer overflow errors. |
Large input array size exceeding memory limitations | Optimize memory usage by potentially using a 1D DP array instead of a 2D array, or consider alternative algorithms if DP is impractical. |
All elements are the same value. | This is a valid case, and the solution should return true if the array has an even number of elements greater than 1, and false otherwise. |