leetcode
leetcode 2601 ~ 2650
按规则计算统计结果

按规则计算统计结果

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 68 ms, 内存: 22.5 MB


/*
 * 思路:
 * 1. 使用 Java Stream 计算数组总乘积 totalProduct。
 * 2. 使用 map 操作生成结果数组 arrayB。
 */
import java.util.stream.*;

public class Solution {
    public int[] productExceptSelf(int[] arrayA) {
        int totalProduct = IntStream.of(arrayA).reduce(1, (a, b) -> a * b);
        return IntStream.of(arrayA).map(x -> totalProduct / x).toArray();
    }
}

解释

方法:

该题解通过两次遍历数组来构建结果数组 `arrayB`。第一次遍历从左到右,用来计算每个位置左边所有元素的乘积;第二次遍历从右到左,用来将之前计算的结果乘以该位置右边所有元素的乘积。这样,每个位置上的值最终就是除了自己以外所有其他元素的乘积。具体做法为:第一次遍历时,用一个累乘的方式计算当前位置左边所有元素的乘积,并存储到 `arrayB` 中。第二次遍历时,用一个变量 `right` 来累乘当前位置右边的元素,并更新 `arrayB[i]`。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在第一次遍历中,如何确保初始化值`b[0]`为1是正确的,而不会对最终结果造成影响?
在题解的算法中,初始化`b[0]`为1是因为每个位置上的值应该是其左右两侧所有元素的乘积。对于第一个元素`b[0]`,其左侧没有任何元素,因此左侧的乘积应该是乘法的单位元素,即1。这保证了`b[0]`在第一次遍历结束时正确地代表了左侧的乘积,而不会影响最终结果。
🦆
考虑到数组`arrayA`的每个元素都参与乘积,如果数组中存在0,该算法如何处理?是否需要特殊处理来避免整个乘积为0?
本算法处理数组中存在0的情况时,不需要特殊处理。由于算法是分别计算左侧和右侧的乘积,如果`arrayA`中的某个位置i是0,则在计算`b[i]`时,其左侧或右侧乘积会包含这个0,自然使得`b[i]=0`。对于其他位置j,只要它们的乘积中不包含这个0(即0不在它们的左侧或右侧),它们的值不会受到影响。如果`arrayA`中有多个0,则除了那些0的位置外,其他所有位置的乘积也将为0。
🦆
算法中提到使用一个额外的变量`right`来保存右侧的乘积,这种方法在遇到数组长度非常大时效率如何?是否会有性能瓶颈?
使用变量`right`来保存右侧的乘积是一种空间效率高的方法,因为它避免了额外数组的需求。这种方法涉及两次遍历,每次遍历的时间复杂度均为O(n),因此总的时间复杂度仍为O(n)。在处理非常大的数组时,这种方法的时间效率是线性的,不存在额外的性能瓶颈。
🦆
在反向遍历过程中,如何处理数组的边界情况,比如`i = n-2`时,`right`的初始值是如何确定的?
在反向遍历开始之前,`right`被初始化为1,这与左侧乘积类似,代表了乘法的单位元素,因为数组的最右端元素右侧没有其他元素。当`i = n-2`时(即数组的倒数第二个元素),`right`的值更新为`a[n-1]`(即最后一个元素的值),这是因为当遍历到倒数第二个元素时,其右侧只有一个元素。此后,每向左移动一个位置,`right`都会乘以当前位置右侧的第一个元素,这样每个位置的`right`都正确地表示了该位置右侧所有元素的乘积。

相关问题