Given an integer array nums
, determine if you can partition the array into two subsets such that the sum of elements in both subsets is equal.
For example:
nums = [1, 5, 11, 5]
should return true
because the array can be partitioned as [1, 5, 5]
and [11]
.nums = [1, 2, 3, 5]
should return false
because the array cannot be partitioned into equal sum subsets.Consider these constraints:
1 <= nums.length <= 200
1 <= nums[i] <= 100
Explain your approach with a time and space complexity analysis. Provide code implementation in Python.
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:
The brute force approach to determine if a set can be partitioned into two equal sum subsets involves exploring all possible combinations of elements. We aim to exhaustively check every possible subset and its complement. If we find one subset that sums to half the total sum, we know a partition is possible.
Here's how the algorithm would work step-by-step:
def can_partition_equal_subset_sum(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 can_find_subset(index, current_sum):
# If the current sum equals the target, we found a partition
if current_sum == target_sum:
return True
# If the index is out of bounds or the current sum exceeds
# the target, stop the search
if index >= len(numbers) or current_sum > target_sum:
return False
# Explore both possibilities: include and exclude the current number
include_current_number = can_find_subset(index + 1, current_sum + numbers[index])
# Check if a partition can be found by excluding the current number.
exclude_current_number = can_find_subset(index + 1, current_sum)
#If either branch returned true, then short circuit and return
return include_current_number or exclude_current_number
# Start the recursion from the beginning
return can_find_subset(0, 0)
The problem asks if a group of numbers can be divided into two subgroups that have the same total. The trick is to realize that if such a division is possible, each subgroup must add up to exactly half of the total sum of all the numbers. We'll use this idea to figure it out efficiently.
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
# dp[i][j] is true if a subset of the first i elements can sum to j
dp_table = [[False for _ in range(target_sum + 1)] for _ in range(len(numbers) + 1)]
# An empty set can always form a sum of 0
for i in range(len(numbers) + 1):
dp_table[i][0] = True
for i in range(1, len(numbers) + 1):
for current_sum in range(1, target_sum + 1):
#If current number is greater than current sum, exclude it
if numbers[i-1] > current_sum:
dp_table[i][current_sum] = dp_table[i-1][current_sum]
else:
# Check if sum can be obtained by including or excluding
dp_table[i][current_sum] = (dp_table[i-1][current_sum] or
dp_table[i-1][current_sum-numbers[i-1]])
# The bottom right corner contains the answer
return dp_table[len(numbers)][target_sum]
Case | How to Handle |
---|---|
Empty input array | Return true because an empty set can be partitioned into two empty sets with equal sum (both zero). |
Array with a single element | Return false, since a single element cannot be partitioned into two subsets with equal sum unless the single element itself is zero (which should return true). |
Array with a very large number of elements (performance) | Dynamic programming solution should scale reasonably well to larger inputs as long as the sum does not overflow, but memoization is essential to avoid exponential time complexity. |
Array with all identical numbers | If the sum is even, it's always possible; if odd, it's not. |
Array containing negative numbers | This problem is defined to only use positive numbers, reject negative number inputs. |
Array sum is odd (no solution possible) | Immediately return false if the sum of the array elements is odd, as an even sum is required for partitioning. |
Array contains zero(s) | Zeroes do not affect the target sum, but handle edge cases for zeroes appropriately depending on whether the solution accounts for them directly or indirectly. |
The sum of the array exceeds the maximum integer value | Use a data type with a larger range to store the sum, or handle the overflow condition appropriately (e.g. prevent calculation and return false). |