561. Array Partition
561. Array Partition
Problem Statement
Given an integer array nums of 2n integers, group these integers into n pairs (a1, b1), (a2, b2), ..., (an, bn) such that the sum of min(ai, bi) for all i is maximized. Return the maximized sum.
Examples
Example 1:
Input: nums = [1,4,3,2]
Output: 4
Explanation: All possible pairings (ignoring the ordering of elements) are:
1. (1, 4), (2, 3) -> min(1,4) + min(2,3) = 1 + 2 = 3
2. (1, 3), (2, 4) -> min(1,3) + min(2,4) = 1 + 2 = 3
3. (1, 2), (3, 4) -> min(1,2) + min(3,4) = 1 + 3 = 4
So the maximum possible sum is 4.
Example 2:
Input: nums = [6,2,6,5,1,2]
Output: 9
Explanation: The optimal pairing is (2, 1), (2, 5), (6, 6). min(2, 1) + min(2, 5) + min(6, 6) = 1 + 2 + 6 = 9.
Constraints
1 <= n <= 10^4nums.length == 2 * n-10^4 <= nums[i] <= 10^4
Clarification Questions
Before diving into the solution, here are 5 important clarifications and assumptions to discuss during an interview:
-
Pairing requirement: Must we pair all elements? (Assumption: Yes - array length is 2n, so we form exactly n pairs)
-
Pair sum calculation: How is the sum calculated? (Assumption: Sum of minimum values from each pair - min(pair1) + min(pair2) + … + min(pairN))
-
Optimization goal: What are we optimizing for? (Assumption: Maximize the sum of minimums from pairs)
-
Pairing strategy: Can we choose which elements to pair? (Assumption: Yes - we can arrange pairs optimally to maximize the sum)
-
Element reuse: Can an element be used in multiple pairs? (Assumption: No - each element appears exactly once)
Interview Deduction Process (10 minutes)
Step 1: Brute-Force Approach (2 minutes)
Initial Thought: “I need to maximize sum of minimums. Let me try all possible pairings.”
Naive Solution: Try all possible ways to pair 2n elements into n pairs, compute sum of minimums, find maximum.
Complexity: O((2n)! / (2^n × n!)) time, O(n) space
Issues:
- Factorial time complexity
- Tries many invalid pairings
- Very inefficient
- Doesn’t leverage sorting property
Step 2: Semi-Optimized Approach (3 minutes)
Insight: “To maximize sum of minimums, I should pair smallest elements together.”
Improved Solution: Sort array. Pair smallest two elements, next smallest two, etc. Sum minimums from each pair.
Complexity: O(n log n) time, O(1) space
Improvements:
- Sorting enables optimal pairing
- O(n log n) time is much better
- Greedy approach is correct
- Handles all cases correctly
Step 3: Optimized Solution (5 minutes)
Final Optimization: “Sorting and pairing adjacent elements is optimal.”
Best Solution: Sort array, pair elements at indices (0,1), (2,3), …, (2n-2, 2n-1). Sum minimums (which are elements at even indices after sorting).
Complexity: O(n log n) time, O(1) space
Key Realizations:
- Sorting is key insight
- Pairing smallest elements maximizes sum of minimums
- O(n log n) time is optimal for sorting approach
- Greedy approach works perfectly
Solution Approach
This is a greedy algorithm problem. The key insight is that to maximize the sum of minimums, we should pair the smallest numbers together, so that larger numbers are “saved” for other pairs.
Key Insights:
- Sort First: Sort the array to process numbers in order
- Greedy Pairing: Pair consecutive elements after sorting
- Take Minimums: Sum the smaller element in each pair (which is the first element after sorting)
- Optimal: This greedy strategy maximizes the sum
Algorithm:
- Sort: Sort the array in ascending order
- Pair: Group elements into pairs
(nums[0], nums[1]), (nums[2], nums[3]), ... - Sum: Sum the first element of each pair (the minimum in each pair)
- Return: The maximized sum
Solution
Solution: Greedy with Sorting
class Solution {
public:
int arrayPairSum(vector<int>& nums) {
sort(nums.begin(), nums.end());
int sum = 0;
for(int i = 0; i < (int)nums.size(); i += 2) {
sum += nums[i];
}
return sum;
}
};
Algorithm Explanation:
- Sort Array (Line 4):
- Sort
numsin ascending order - This ensures smaller numbers come first
- Sort
- Sum Minimums (Lines 5-8):
- Initialize:
sum = 0 - For each pair: Iterate with step 2 (
i += 2)- After sorting, pairs are
(nums[i], nums[i+1]) - The minimum in each pair is
nums[i](smaller element) - Add
nums[i]to sum
- After sorting, pairs are
- Initialize:
- Return (Line 9):
- Return the accumulated sum
Example Walkthrough:
Example 1: nums = [1,4,3,2]
After sorting:
Original: [1, 4, 3, 2]
Sorted: [1, 2, 3, 4]
Pairing and summing:
Pair 1: (1, 2) → min = 1
Pair 2: (3, 4) → min = 3
Sum: 1 + 3 = 4
Execution:
Initial: sum = 0
i=0: nums[0]=1
sum = 0 + 1 = 1
i=2: nums[2]=3
sum = 1 + 3 = 4
Result: 4
Example 2: nums = [6,2,6,5,1,2]
After sorting:
Original: [6, 2, 6, 5, 1, 2]
Sorted: [1, 2, 2, 5, 6, 6]
Pairing and summing:
Pair 1: (1, 2) → min = 1
Pair 2: (2, 5) → min = 2
Pair 3: (6, 6) → min = 6
Sum: 1 + 2 + 6 = 9
Execution:
Initial: sum = 0
i=0: nums[0]=1
sum = 0 + 1 = 1
i=2: nums[2]=2
sum = 1 + 2 = 3
i=4: nums[4]=6
sum = 3 + 6 = 9
Result: 9
Algorithm Breakdown
Why Greedy Works
The greedy strategy is optimal because:
- Minimize Loss: By pairing smallest with second smallest, we minimize the “waste” from the larger number
- Maximize Minimums: This strategy maximizes the sum of minimums
- No Better Pairing: Any other pairing would result in a smaller sum
Mathematical Proof:
- If we pair
(a, b)wherea < b, we getain the sum - If we pair
(a, c)wherec > b, we still geta, butbmight be paired with a smaller number, reducing the sum - Therefore, pairing consecutive elements after sorting is optimal
Key Insight: Pair Consecutive Elements
After sorting, the optimal pairing is:
(nums[0], nums[1])(nums[2], nums[3])(nums[4], nums[5])- …
This ensures:
- Each pair has the smallest possible difference
- The sum of minimums is maximized
Why Not Pair Differently?
Counter-example:
nums = [1, 2, 3, 4]
Pairing 1 (optimal): (1,2), (3,4)
Sum: min(1,2) + min(3,4) = 1 + 3 = 4
Pairing 2: (1,3), (2,4)
Sum: min(1,3) + min(2,4) = 1 + 2 = 3
Pairing 3: (1,4), (2,3)
Sum: min(1,4) + min(2,3) = 1 + 2 = 3
Pairing consecutive elements gives the maximum sum.
Time & Space Complexity
- Time Complexity: O(n log n) where n is the length of the array
- Dominated by sorting: O(n log n)
- Iteration: O(n) - single pass with step 2
- Total: O(n log n)
- Space Complexity: O(1)
- Only using a few variables
- Sorting is in-place (or O(n) if not in-place, but typically O(1) extra space)
Key Points
- Sort First: Essential for greedy strategy
- Greedy Pairing: Pair consecutive elements after sorting
- Sum Minimums: Add the first element of each pair
- Optimal: Greedy approach finds maximum sum
- Simple: Straightforward implementation after sorting
Alternative Approaches
Approach 1: Greedy with Sorting (Current Solution)
- Time: O(n log n)
- Space: O(1)
- Best for: Optimal solution, most efficient
Approach 2: Try All Pairings
- Time: O((2n)! / (2^n × n!))
- Space: O(n)
- Not practical: Too slow for large inputs
Approach 3: Dynamic Programming
- Time: O(n²)
- Space: O(n²)
- Overkill: Not needed, greedy is optimal
Edge Cases
- All same values:
[1,1,1,1]→ return 2 (1+1) - Negative numbers:
[-1,-2,-3,-4]→ return -6 (-1 + -3) - Mixed signs:
[-1,2,-3,4]→ return -1 (-3 + 2) - Two elements:
[1,2]→ return 1 - Large range:
[1,100,2,99]→ return 3 (1+2)
Common Mistakes
- Not sorting: Trying to pair without sorting
- Wrong pairing: Not pairing consecutive elements
- Wrong sum: Summing both elements instead of minimum
- Index error: Off-by-one errors in loop
- Negative numbers: Forgetting to handle negative numbers correctly
Related Problems
- 455. Assign Cookies - Greedy matching
- 561. Array Partition - Current problem
- 628. Maximum Product of Three Numbers - Greedy with sorting
- 462. Minimum Moves to Equal Array Elements II - Median-based greedy
Tags
Array, Greedy, Sorting, Easy