leetcode238-除自身以外数组的乘积

leetcode 238
在这里插入图片描述

思路

可以在不使用除法的情况下,利用前缀积后缀积来实现解答

  • 前缀积:对每个位置,计算当前数字左侧的所有数字的乘积
  • 后缀积:对每个位置,计算当前数字右侧的所有数字的乘积
    结合这两种思想,可以在一次遍历中完成计算
    步骤:
  • 第一次遍历,计算每个位置左侧的前缀积,并直接保存在 answer 中
  • 第二次遍历,从右往左计算右侧的后缀积,并与 answer 中存储的前缀积相乘,得到最终结果

前缀积部分
使用一个变量 prefix 初始化为 1,遍历数组 nums,对于每个位置 i,将 prefix 保存到 answer[i] 中,并更新 prefix 为 prefix * nums[i]。这样,answer[i] 存储的是 nums 数组中所有 i 左边元素的乘积
后缀积部分
使用一个变量 suffix 初始化为 1,从数组的右侧开始遍历。对于每个位置 i,将 suffix 与 answer[i] 相乘,更新 suffix 为 suffix * nums[i]。这样,answer[i] 最终保存的是 i 左右两边元素的乘积

时间复杂度:O(n) 空间复杂度:O(1)

假设nums = [1,2,3,4]
前缀积得到的nums = [1,1,2,6] 每个元素左侧的乘积
后缀积得到的nums = [24,12,8,6]

实现

var productExceptSelf = function (nums) {
    let len = nums.length;
    const answer = new Array(len).fill(1)
    let prefix = 1;
    // 计算前缀积
    for (let i = 0; i < nums.length; i++) {
        answer[i] = prefix;
        prefix *= nums[i]
    }
    let suffix = 1;
    // 计算后缀积
    for (let i = len - 1; i >= 0; i--) {
        answer[i] = answer[i] * suffix;
        suffix *= nums[i]
    }
    return answer;
};
### LeetCode Hot 100 '自身以外数组乘积' Java 解决方案 对于给定的一个整数数组 `nums`,目标是构建一个新的数组 `answer`,使得 `answer[i]` 是了 `nums[i]` 外所有元素的乘积。此问题可以通过两次遍历实现,在不使用额外空间的情况下完成计算。 #### 方法概述 通过两个方向的扫描来解决问题:一次正向扫描用于累积左侧部分的结果;另一次反向扫描则更新右侧部分并最终形成完整的解法[^2]。 #### 正向扫描 初始化一个变量 `leftProduct` 来保存当前索引左边所有数字相乘得到的结果,并将其赋值给新创建的答案列表对应位置上。随着迭代过程不断更新这个累加器以便后续使用。 ```java public class Solution { public int[] productExceptSelf(int[] nums) { int length = nums.length; int[] answer = new int[length]; // 初始化为1是因为任何数与1相乘都等于其本身 int leftProduct = 1; for (int i = 0; i < length; ++i){ answer[i] = leftProduct; leftProduct *= nums[i]; } ``` #### 反向扫描 接着从右至左再次遍历输入数组的同时维护另一个临时变量 `rightProduct` 记录右边元素连乘结果。每一步都将之前存储好的左侧产品乘以此时获得的新因子存入答案数组相应下标的格子内。 ```java int rightProduct = 1; for (int i = length - 1; i >= 0; --i){ answer[i] *= rightProduct; rightProduct *= nums[i]; } return answer; } } ``` 这种方法不仅满足题目要求的空间复杂度 O(1),而且时间效率也达到了最优水平——线性的O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值