📌  相关文章
📜  数组中对的最小值的最大和(1)

📅  最后修改于: 2023-12-03 15:26:11.136000             🧑  作者: Mango

数组中对的最小值的最大和

在给定的数组中,我们可以形成许多的对,每个对包含两个不同的元素。我们需要找到所有的对中,最小值的和最大的那个对,返回它们最小值的和。

例如,对于数组 [3, 5, 2, 6],存在以下的所有对:

(3, 5)
(3, 2)
(3, 6)
(5, 2)
(5, 6)
(2, 6)

它们的最小值依次为 3, 2, 3, 2, 5, 2。其中,最小值为 2 的对有两个 (3, 2)(5, 2)。它们的最小值和为 2 + 2 = 4,因此函数应该返回 4

其他的例子:

输入:[1, 2, 4, 5]
输出:4
输入:[2, 2, 2, 2, 2]
输出:4
思路

可以使用贪心算法解决本题。对于任意的两个元素,它们可以组成一个对。我们需要找到所有的对中,最小值最大的那个对。

考虑假设最小值为 x,那么我们需要找到数组中所有的对中,最小值大于等于 x 的那个对。在找到这个对之后,我们将它们的最小值累加到答案中。

那么关键问题就是如何快速找到一个最小值大于等于 x 的对。有一种简单的方法是使用双重循环,但是时间复杂度为 $O(n^2)$。事实上,我们可以使用一些更高效的算法。

首先,我们可以将数组排序,将时间复杂度降至 $O(n \log n)$。在排序之后,我们可以使用双指针的方法,从两端排除元素,以找到最小值大于等于 x 的对。具体来说,对于当前的最小值 x,我们维护两个指针 ij,使得数组中 0 ~ i-1j+1 ~ n-1 的元素都小于 x,而 ij 是最小值大于等于 x 的两个元素的下标,它们之间的所有元素都大于等于 x

这样,我们就可以用 $O(n \log n)$ 的时间复杂度解决本问题。

代码实现
from typing import List

def getMinSum(nums: List[int]) -> int:
    nums.sort()
    n = len(nums)
    ans = float('inf')
    for i in range(n):
        j = n - 1
        while j > i and nums[i] + nums[j] >= ans:
            j -= 1
        if j > i:
            ans = min(ans, nums[i] + nums[j])
    return ans
复杂度分析

时间复杂度:$O(n \log n)$

空间复杂度:$O(1)$

其中,空间复杂度为排序所用的栈空间,因此可以忽略。