Balanced Partition
January 8, 2024
Problem #
You are given an array nums of integers. Write a function to determine if the array can be partitioned into two subsets such that the sum of elements in both subsets is the same.
Example: #
Input: nums = [1, 5, 11, 5]
Output: True
Explanation: The array can be partitioned as [1, 5, 5] and [11].
Solution #
The problem is a variation of the “Subset Sum” problem, which is a classic dynamic programming issue. The idea is to determine if there is a subset whose sum is equal to half of the total sum of the array. If such a subset exists, it implies the array can be divided into two subsets with equal sums.
Algorithm Steps: #
- Calculate the total sum of the array. If the sum is odd, return False because the array cannot be partitioned into two equal subsets.
- Use dynamic programming to find if there’s a subset with a sum equal to half of the total sum.
- Create a boolean 2D array
dpwith dimensions[n+1][sum/2 + 1]wherenis the number of elements innums. - Initialize the first column of
dpas True (since a sum of 0 is always possible). - Fill the
dparray according to the subset sum problem solution. - Return
dp[n][sum/2].
Code in Python: #
def canPartition(nums):
total_sum = sum(nums)
if total_sum % 2 != 0:
return False
subset_sum = total_sum // 2
n = len(nums)
dp = [[False for _ in range(subset_sum + 1)] for _ in range(n + 1)]
for i in range(n + 1):
dp[i][0] = True
for i in range(1, n + 1):
for j in range(1, subset_sum + 1):
if j < nums[i - 1]:
dp[i][j] = dp[i - 1][j]
else:
dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]]
return dp[n][subset_sum]
# Example Usage
print(canPartition([1, 5, 11, 5])) # Output: True
Code Analysis #
The provided Python code is a solution for the “Balanced Partition” problem, which determines whether an array can be partitioned into two subsets with equal sums. Let’s go through the code step by step:
-
Function Definition:
def canPartition(nums):This defines a function named
canPartitionthat takes an arraynumsas input. -
Calculate Total Sum and Initial Check:
total_sum = sum(nums) if total_sum % 2 != 0: return FalseThe total sum of all elements in
numsis calculated. If this sum is odd (total_sum % 2 != 0), it’s impossible to split the array into two equal-sum subsets, so the function immediately returnsFalse. -
Prepare for Dynamic Programming:
subset_sum = total_sum // 2 n = len(nums) dp = [[False for _ in range(subset_sum + 1)] for _ in range(n + 1)]The target subset sum (
subset_sum) is half of the total sum. Thedparray is a 2D list of size(n+1) x (subset_sum+1)initialized toFalse. Each elementdp[i][j]will indicate whether there is a subset among the firstinumbers ofnumsthat sums up toj. -
Initialize First Column of DP Array:
for i in range(n + 1): dp[i][0] = TrueThis initializes the first column of the
dparray toTrue. This is because a subset sum of0is always possible (by selecting no elements). -
Fill the DP Table:
for i in range(1, n + 1): for j in range(1, subset_sum + 1): if j < nums[i - 1]: dp[i][j] = dp[i - 1][j] else: dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]]This nested loop fills up the
dptable. For each elementnums[i-1](considering 1-based indexing for clarity), and for each possible sumj:- If
j(the target sum) is less thannums[i-1], we can’t include this element, so we inherit the value fromdp[i-1][j]. - Otherwise, we check if we can form the sum either by excluding (
dp[i-1][j]) or including (dp[i-1][j - nums[i - 1]]) the current element.
- If
-
Return the Result:
return dp[n][subset_sum]Finally, the function returns the value of
dp[n][subset_sum], which indicates whether it’s possible to achieve a subset sum ofsubset_sumusing all elements ofnums.
Overall, the code uses a dynamic programming approach to efficiently solve a problem that might seem daunting if tackled with brute force methods. By breaking the problem into smaller subproblems and storing intermediate results, it achieves polynomial time complexity.
Time Complexity: #
O(n * sum/2), where n is the number of elements in nums and sum is the total sum of the array. This is due to the nested loop in the dynamic programming solution.
Space Complexity: #
O(n * sum/2), for the 2D dp array.
This problem is an excellent example of applying dynamic programming to partition problems, balancing computational efficiency with a straightforward approach.