目录
题目:
概述:
一个数对 (a,b) 的 数对和 等于 a + b 。最大数对和 是一个数对数组中最大的 数对和 。
- 比方说,如果我们有数对 (1,5) ,(2,3) 和 (4,4),最大数对和 为 max(1+5, 2+3, 4+4) = max(6, 5, 8) = 8 。
给你一个长度为 偶数 n 的数组 nums ,请你将 nums 中的元素分成 n / 2 个数对,使得:
- nums 中每个元素 恰好 在 一个 数对中,且
- 最大数对和 的值 最小 。
请你在最优数对划分的方案下,返回最小的 最大数对和 。
示例 1:
输入:nums = [3,5,2,3]
输出:7
解释:数组中的元素可以分为数对 (3,3) 和 (5,2) 。
最大数对和为 max(3+3, 5+2) = max(6, 7) = 7 。
示例 2:
输入:nums = [3,5,4,2,4,6]
输出:8
解释:数组中的元素可以分为数对 (3,5),(4,4) 和 (6,2) 。
最大数对和为 max(3+5, 4+4, 6+2) = max(8, 8, 8) = 8 。
提示:
- n == nums.length
- 2 <= n <= 105
- n 是 偶数 。
- 1 <= nums[i] <= 105
本人解答(java):
class Solution {
public int minPairSum(int[] nums) {
Arrays.sort(nums);
int len = nums.length;
int left = 0, right = len - 1;
int ans = 0;
while (left < right) {
ans = Math.max(nums[left++] + nums[right--], ans);
}
return ans;
}
}
官方解答:
方法:排序 + 贪心
提示 1
数组内只有两个数的情况是平凡的。我们可以考虑数组中只有四个数x1
≤ x2 ≤ x3 ≤ x4 的情况。此时 (x1, x4), (x2, x3) 的拆分方法对应的最大数对和一定是最小的。
提示 1 解释
我们可以枚举所有的拆分方法。除了上文的拆分方法外还有两种拆分方法:
-
(x1,x3) , (x2,x4)
此时x2+x4 ≥ x1+x4且x2+x4 ≥x2+x3。
那么max(x1+x3 , x2+x4) ≥ x2+x4 ≥ max(x1+x4,x2+x3)。
- (x1,x2) , (x3,x4)
同样的,max(x1+x2 , x3+x4) ≥ x3+x4 ≥ max(x1+x4 , x2+x3)。
提示 2
对于 n 个数(n 为偶数)的情况,上述的条件对应的拆分方法,即第 k 大与第 k 小组成的 n/2 个数对,同样可以使得最大数对和最小。
提示 2 解释
我们可以类似 提示 1 对所有数建立全序关系,即X1 ≤ …… ≤ Xn。我们需要证明,任意的拆分方法得到的最大数对和一定大于等于给定的拆分方法得到的最大数对和。
我们可以考虑上述命题的充分条件:假设给定拆分方法中的数对和Xk+Xn+1-k在k=k' 时最大,那么对于任意的拆分方法,都存在一组 u, v使得 Xu+Xv ≥ Xk'+Xn+1-k'。
我们可以用反证法证明。
同样,我们假设 u < v,那么使得Xv ≥ Xn+1-k'的 v 的取值一共有 k'种。即闭区间[n+1-k',n]
中的所有整数。对于这些 v 组成的数对,如果想使得 Xu + Xv < Xk' + Xn+1-k' 恒成立,必须要 Xu < Xk'。此时需要有 k'个不同的 u 的取值,但只有闭区间 [1,k'-1]中的 k'-1 个整数满足Xu < Xk'的条件,这就产生了矛盾。
因此,一定存在一组 u, v 使得Xu+Xv ≥ Xk'+Xn+1-k'。
思路与算法
根据 提示 2,我们需要将 nums 排序。排序后,我们遍历每一个第 k 大与第 k 小组成的数对,计算它们的和,并维护这些和的最大值。同样根据 提示 2,遍历完成后求得的最大数对和就是满足要求的最小值。
C代码:
int cmp(int *a, int *b) {
return *a - *b;
}
int minPairSum(int *nums, int numsSize) {
int res = 0;
qsort(nums, numsSize, sizeof(int), cmp);
for (int i = 0; i < numsSize / 2; ++i) {
res = fmax(res, nums[i] + nums[numsSize - 1 - i]);
}
return res;
}
Java代码:
class Solution {
public int minPairSum(int[] nums) {
int n = nums.length;
int res = 0;
Arrays.sort(nums);
for (int i = 0; i < n / 2; ++i) {
res = Math.max(res, nums[i] + nums[n - 1 - i]);
}
return res;
}
}
C++代码:
class Solution {
public:
int minPairSum(vector<int>& nums) {
int n = nums.size();
int res = 0;
sort(nums.begin(), nums.end());
for (int i = 0; i < n / 2; ++i) {
res = max(res, nums[i] + nums[n - 1 - i]);
}
return res;
}
};
go代码:
func minPairSum(nums []int) (ans int) {
sort.Ints(nums)
n := len(nums)
for i, val := range nums[:n/2] {
ans = max(ans, val+nums[n-1-i])
}
return
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
python代码:
class Solution:
def minPairSum(self, nums: List[int]) -> int:
n = len(nums)
res = 0
nums.sort()
for i in range(n // 2):
res = max(res, nums[i] + nums[n-1-i])
return res
来源:
力扣(LeetCode)
链接:
https://leetcode-cn.com/problems/minimize-maximum-pair-sum-in-array