leetcode
leetcode 2251 ~ 2300
左右元素和的差值

左右元素和的差值

难度:

标签:

题目描述

Given a 0-indexed integer array nums, find a 0-indexed integer array answer where:

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

Where:

  • leftSum[i] is the sum of elements to the left of the index i in the array nums. If there is no such element, leftSum[i] = 0.
  • rightSum[i] is the sum of elements to the right of the index i in the array nums. If there is no such element, rightSum[i] = 0.

Return the array answer.

 

Example 1:

Input: nums = [10,4,8,3]
Output: [15,1,11,22]
Explanation: The array leftSum is [0,10,14,22] and the array rightSum is [15,11,3,0].
The array answer is [|0 - 15|,|10 - 11|,|14 - 3|,|22 - 0|] = [15,1,11,22].

Example 2:

Input: nums = [1]
Output: [0]
Explanation: The array leftSum is [0] and the array rightSum is [0].
The array answer is [|0 - 0|] = [0].

 

Constraints:

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

代码结果

运行时间: 27 ms, 内存: 16.3 MB


/*
 * 题目思路:
 * 通过使用 Java Stream 来计算 leftSum 和 rightSum。
 * 我们首先使用 Stream 来生成 leftSum 和 rightSum,
 * 然后用 mapToInt 方法计算绝对值差。
 */
import java.util.stream.*;

public class Solution {
    public int[] leftRightDifference(int[] nums) {
        int n = nums.length;
        int[] leftSum = new int[n];
        int[] rightSum = new int[n];

        // 计算 leftSum 数组
        IntStream.range(1, n).forEach(i -> leftSum[i] = leftSum[i - 1] + nums[i - 1]);

        // 计算 rightSum 数组
        IntStream.iterate(n - 2, i -> i >= 0, i -> i - 1).forEach(i -> rightSum[i] = rightSum[i + 1] + nums[i + 1]);

        // 计算 answer 数组
        return IntStream.range(0, n)
                .map(i -> Math.abs(leftSum[i] - rightSum[i]))
                .toArray();
    }
}

解释

方法:

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

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在算法的描述中,如何处理数组中只有一个元素的情况?
在数组只有一个元素的情况下,初始化时leftsum为0,rightsum也为0(因为除了第一个元素外没有其他元素)。在遍历过程中,由于数组只有一个元素,循环体不会执行。在循环外部处理最后一个元素时,此时leftsum和rightsum均为0,因此计算的差的绝对值也为0。最终函数将返回包含单个0的列表。这种处理方式确保了算法对于任何长度的数组都是健壮的。
🦆
为什么在for循环的迭代中不包括数组的最后一个元素,然后在循环外单独处理?是否有可能在循环内部一次性处理完所有元素?
循环中不包括数组的最后一个元素,是为了在每次迭代中能够安全地访问nums[i+1],并从rightsum中减去这个值,更新右侧的和。如果循环包括了最后一个元素,那么在最后一次迭代中访问nums[i+1]将会导致数组越界错误,因为i+1不存在。虽然可以通过修改循环条件和内部逻辑来在循环内处理所有元素,但这通常会使代码复杂化,增加特殊情况的处理,因此单独在循环外处理最后一个元素可以使逻辑更清晰、更安全。
🦆
在更新rightsum时,如果当前元素是数组的最后一个元素,减去nums[i+1]是否会导致数组越界错误?
在原始代码中,循环是不包括数组的最后一个元素的,这意味着在执行rightsum -= nums[i+1]时,i+1始终是有效的数组索引。循环的设计确保了我们不会尝试访问一个不存在的数组元素,从而避免了数组越界错误。这样的设计是为了确保算法的安全执行,防止运行时错误。

相关问题