📌  相关文章
📜  由 O(n) 中数组的数字组成的两个数字的最小和(1)

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

由 O(n) 中数组的数字组成的两个数字的最小和

问题描述

给定一个长度为 n 的整数数组 nums,从中选出两个数字组成一个数对(x,y),使得其和最小。

设计一个算法,使其复杂度为 O(n)。

解决方案

我们可以使用双指针来解决这个问题。

首先对数组进行排序,然后使用两个指针,一个指向数组的起始位置,另一个指向数组的末尾位置。

每次将两个指针指向的数字相加,并记录它们的和,如果该和小于当前的最小和,则更新最小和的值。然后将较小数字的指针向前移动一位,再进行下一轮比较。

最终,当两个指针相遇时,找到了数组中两个数字的和最小的数对。

代码:

def min_sum(nums):
    nums.sort()
    i, j = 0, len(nums)-1
    min_sum = float('inf')
    while i < j:
        s = nums[i] + nums[j]
        min_sum = min(min_sum, s)
        if s < min_sum:
            min_sum = s
        if s < 0:
            i += 1
        else:
            j -= 1
    return min_sum

时间复杂度:O(nlogn)(排序所需的时间)。

但是由于题目要求时间复杂度为 O(n),这里还需要使用一些技巧。

由于数组已经排序,所以如果一个数对 (x,y) 的和为负数,那么再加上一个较小的数得到的结果肯定更小。

因此,在双指针移动过程中,当两个指针所指向数字的和为负数时,将较小数字的指针向前移动一位,即 i += 1,否则将较大数字的指针向后移动一位,即 j -= 1。

这样,我们就可以使时间复杂度为 O(n)。

代码:

def min_sum(nums):
    nums.sort()
    i, j = 0, len(nums)-1
    min_sum = float('inf')
    while i < j:
        s = nums[i] + nums[j]
        min_sum = min(min_sum, s)
        if s < 0:
            i += 1
        else:
            j -= 1
    return min_sum
总结

本题利用双指针的思想,结合排序和贪心的思想,找到了 O(n) 时间复杂度的解法,是一道较为简单的题目。