返回

妙用列表前缀和,解 leetcode 2256 题

后端

引言

Leetcode 2256 题**《最小平均差》** 是一道难度为 Medium 的题目,考察的是对列表前缀和 的理解及其应用。

题目如下:

给定一个整数数组 nums,请你找出 两个 子数组 nums[i], nums[i+1], ..., nums[j]nums[k], nums[k+1], ..., nums[l],使得:

  • i <= k <= j <= l
  • 子数组 nums[i], nums[i+1], ..., nums[j]nums[k], nums[k+1], ..., nums[l] 的长度相同, 不小于 2
  • 子数组 nums[i], nums[i+1], ..., nums[j] 的平均值和子数组 nums[k], nums[k+1], ..., nums[l] 的平均值的绝对差 最小

请你返回 ik 的最小可能和。

示例 1:

输入:nums = [2,5,3,9,5,3]
输出:3
解释:我们将数组分成下面两个子数组:
- nums[1] = 5
- nums[4] = 5
这两个子数组的平均值都是 5,所以绝对差为 0,是可能的最小绝对差。

示例 2:

输入:nums = [6,4,6,3,1]
输出:7
解释:我们将数组分成下面两个子数组:
- nums[0] = 6
- nums[2] = 6
这两个子数组的平均值都是 6,所以绝对差为 0,是可能的最小绝对差。

提示:

  • 2 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^4

解题思路

这道题的解题思路相对简单,主要步骤如下:

  1. 计算出数组 nums前缀和 prefix_sum

  2. 遍历数组 nums,枚举子数组 nums[i], nums[i+1], ..., nums[j] 的长度,对于每个长度,计算出子数组 nums[i], nums[i+1], ..., nums[j] 的平均值。

  3. 同时,计算出子数组 nums[k], nums[k+1], ..., nums[l] 的平均值,其中 kl 分别是 ij 的最大值和最小值。

  4. 计算子数组 nums[i], nums[i+1], ..., nums[j]nums[k], nums[k+1], ..., nums[l] 的平均值的绝对差

  5. 将绝对差的最小值及其对应的 ik 的值记录下来。

  6. 最终返回 ik 的最小可能和。

代码实现

以下是用 Python 实现的完整代码:

def minimumAverageDifference(nums):
    """
    :type nums: List[int]
    :rtype: int
    """
    n = len(nums)
    prefix_sum = [0] * n
    prefix_sum[0] = nums[0]
    for i in range(1, n):
        prefix_sum[i] = prefix_sum[i-1] + nums[i]

    min_diff = float('inf')
    min_i = 0
    min_k = 0
    for i in range(1, n-1):
        for j in range(i+1, n):
            avg1 = (prefix_sum[j] - prefix_sum[i-1]) / (j - i + 1)
            k = j + 1
            l = n - 1
            while k <= l:
                mid = (k + l) // 2
                avg2 = (prefix_sum[mid] - prefix_sum[j]) / (mid - j + 1)
                if abs(avg1 - avg2) < min_diff:
                    min_diff = abs(avg1 - avg2)
                    min_i = i
                    min_k = k
                if avg2 > avg1:
                    l = mid - 1
                else:
                    k = mid + 1

    return min_i + min_k

复杂度分析

  • 时间复杂度:O(n^3),其中 n 是数组 nums 的长度。

  • 空间复杂度:O(n),用于存储前缀和数组 prefix_sum

结语

本题考察了对列表前缀和的理解及其应用,解题思路相对简单,主要步骤是枚举子数组的长度,并计算每个子数组的平均值,最后比较平均值的绝对差。代码实现也不复杂,主要注意边界条件和细节处理。