Reputation: 45
This is a question from leetcode.
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.
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.
I resolved this by trying multiple examples and found out if I sorted and arranged the pair like 1 2 | 3 4
, the min value of each pair is what I want. Since the array is sorted, the positions of min values are fixed; hence I can get the value by index + 2. Although it works, it's more like a guss. Does anyone know how to prove this in mathematics to make the logic more rigourously?
def arrayPairSum(nums: List[int]) -> int:
nums_sort = sorted(nums)
res = 0
i = 0
while i < len(nums):
res += nums_sort[i]
i += 2
return res
Upvotes: 1
Views: 1638
Reputation: 114548
You can use induction. Let's say you have a sorted array a
. The smallest number, a[0]
will always be the smallest of whatever pair it occurs in. The maximum sum will occur if you select its partner to be a[1]
, the next smallest number. You can show this by selecting some other number a[m]
to be its partner. In that case, at least one of the other pairs will have minimum a[1]
, which is by definition less than it would otherwise have. You can proceed to apply the same argument to the remaining elements a[2:]
.
Alternatively, you can start from the other end. a[-1]
is guaranteed to never figure in the sum because it is the maximum of whatever pair it will occur in. If you pair it with anything other than a[-2]
, the total sum will not be maximized: some smaller a[m]
will represent the pair containing a[-1]
in the sum, while a[-2]
will be larger than any a[n]
it is paired with, and therefore will not appear in the sum.
Both arguments yield the same result: the maximum sum is over the even indices of the sorted array.
As mentioned in the comments, the following two implementations will be more efficient than a raw for
loop:
def arrayPairSum(nums: List[int]) -> int:
return sum(sorted(nums)[::2])
OR
def arrayPairSum(nums: List[int]) -> int:
nums.sort()
return sum(nums[::2])
The latter does the sorting in-place, and is probably faster if allowed.
Upvotes: 1