力扣刷题Days30-238. 除自身以外数组的乘积(js)

时间:2024-04-06 18:05:56

目录

1,题目

2,代码

2.1左右乘积列表

2.2优化-空间复杂度常量化

算法实现:

3,学习与总结

3.1记录我的思考过程

3.2本题特点


1,题目

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。

题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32 位 整数范围内。

请 不要使用除法,且在 O(n) 时间复杂度内完成此题。

2,代码

2.1左右乘积列表

维护给定索引处的数字相对应的前缀和后缀;重点在于理解两个列表的初始化过程;

前缀:给定索引左侧所有数字的乘积;

后缀:给定索引右侧所有数字的乘积;

小tips:乘积 利用‘1’;

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var productExceptSelf = function(nums) {
    const n = nums.length;
    let ltable = new Array(n).fill(1);
    let rtable = new Array(n).fill(1);
    let ans = new Array(n).fill(0); 
    for(let i = 1;i < n;i++){
        ltable[i] = ltable[i-1]*nums[i-1];
    }
     for(let i = n-2; i >= 0;i--){
        rtable[i] = rtable[i+1]*nums[i+1];
     }
     for(let i = 0;i < n;i++){
        ans[i] = ltable[i]*rtable[i];
    }

    return ans;

};

2.2优化-空间复杂度常量化

由于输出数组不算在空间复杂度内,那么我们可以将 L 或 R 数组用输出数组来计算。先把输出数组当作 L 数组来计算,然后再动态构造 R 数组得到结果。

/**
 * @param {number[]} nums
 * @return {number[]}
 */
var productExceptSelf = function(nums) {
    const n = nums.length;
    let ans = new Array(n).fill(1);
    
    for(let i = 1;i < n;i++){
        ans[i] = ans[i-1]*nums[i-1];
    }
    // R索引右侧所有数字的乘积
    let R = 1;
    for(let i = n-1; i >= 0;i--){
        ans[i] = ans[i] * R;
        R *= nums[i];
    } 

    return ans;

};
算法实现:
  1. 初始化 ans数组,answer[i] 先代表的是 i 左侧所有数字的乘积。
  2. 用一个遍历来跟踪右边元素的乘积。并更新数组answer[i]=answer[i]∗R。

说明:

R 更新为 R=R∗nums[i]

变量 R表示的就是索引右侧数字的乘积。

3,学习与总结

3.1记录我的思考过程

(1)积累一下对数组中0个数的统计

    const str = nums.join('');
    const n = (str.split('0')).length-1;

(2)我的思路

算出数组中所有数字的乘积,除以相对应索引值;

首先,判断0的个数numsOfzero

numsOfzero >= 2

numsOfzero === 1

numsOfzero === 0

问题在于numsOfzero 等于1或者0的情况需要单独处理,整体代码的实现相对繁琐;

3.2本题特点

要学习处理的方法;

了解处理思路后,可以自己实现代码逻辑,即主要在于解题思路上;


勉励自己:贵在坚持!