左右元素和的差值

标签: 数组 前缀和

难度: Easy

给你一个下标从 0 开始的整数数组 nums ,请你找出一个下标从 0 开始的整数数组 answer ,其中:

  • answer.length == nums.length
  • answer[i] = |leftSum[i] - rightSum[i]|

其中:

  • leftSum[i] 是数组 nums 中下标 i 左侧元素之和。如果不存在对应的元素,leftSum[i] = 0
  • rightSum[i] 是数组 nums 中下标 i 右侧元素之和。如果不存在对应的元素,rightSum[i] = 0

返回数组 answer

示例 1:

输入:nums = [10,4,8,3]
输出:[15,1,11,22]
解释:数组 leftSum 为 [0,10,14,22] 且数组 rightSum 为 [15,11,3,0] 。
数组 answer 为 [|0 - 15|,|10 - 11|,|14 - 3|,|22 - 0|] = [15,1,11,22] 。

示例 2:

输入:nums = [1]
输出:[0]
解释:数组 leftSum 为 [0] 且数组 rightSum 为 [0] 。
数组 answer 为 [|0 - 0|] = [0] 。

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 105

Submission

运行时间: 27 ms

内存: 16.3 MB

class Solution:
    def leftRightDifference(self, nums: List[int]) -> List[int]:
        ans = []
        leftsum, rightsum = 0, sum(nums) - nums[0]
        for i in range(len(nums) - 1):
            ans.append(abs(leftsum - rightsum))
            leftsum += nums[i]
            rightsum -= nums[i + 1]
        ans.append(abs(leftsum - rightsum))
        return ans

Explain

题解采用一次遍历的方法计算左右和的差的绝对值。首先,初始化leftsum为0(因为第一个元素左侧无元素),rightsum为除了第一个元素外的所有元素之和。然后遍历数组,每到一个新的元素i,计算当前的leftsum和rightsum的差的绝对值,并更新leftsum和rightsum,以便在下一次循环时使用。leftsum每次增加当前元素nums[i],而rightsum减去下一个元素nums[i+1](这是因为该元素将从右侧和中移除)。最后,将最后一个元素的差的绝对值也添加到结果中。

时间复杂度: O(n)

空间复杂度: O(n)

class Solution:
    def leftRightDifference(self, nums: List[int]) -> List[int]:
        ans = []  # 结果数组
        leftsum, rightsum = 0, sum(nums) - nums[0]  # 初始化左和为0,右和为除第一个元素外的所有元素和
        for i in range(len(nums) - 1):  # 遍历数组
            ans.append(abs(leftsum - rightsum))  # 计算当前的左右和差的绝对值,添加到结果列表
            leftsum += nums[i]  # 更新左和
            rightsum -= nums[i + 1]  # 更新右和
        ans.append(abs(leftsum - rightsum))  # 最后一个元素的处理
        return ans  # 返回结果数组

Explore

在数组只有一个元素的情况下,初始化时leftsum为0,rightsum也为0(因为除了第一个元素外没有其他元素)。在遍历过程中,由于数组只有一个元素,循环体不会执行。在循环外部处理最后一个元素时,此时leftsum和rightsum均为0,因此计算的差的绝对值也为0。最终函数将返回包含单个0的列表。这种处理方式确保了算法对于任何长度的数组都是健壮的。

循环中不包括数组的最后一个元素,是为了在每次迭代中能够安全地访问nums[i+1],并从rightsum中减去这个值,更新右侧的和。如果循环包括了最后一个元素,那么在最后一次迭代中访问nums[i+1]将会导致数组越界错误,因为i+1不存在。虽然可以通过修改循环条件和内部逻辑来在循环内处理所有元素,但这通常会使代码复杂化,增加特殊情况的处理,因此单独在循环外处理最后一个元素可以使逻辑更清晰、更安全。

在原始代码中,循环是不包括数组的最后一个元素的,这意味着在执行rightsum -= nums[i+1]时,i+1始终是有效的数组索引。循环的设计确保了我们不会尝试访问一个不存在的数组元素,从而避免了数组越界错误。这样的设计是为了确保算法的安全执行,防止运行时错误。