🌈【LeetCode.除自身以外数组的乘积】- JavaScript =>前缀积&后缀积+滚动变量

492 阅读2分钟

「这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


题意描述

给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。

示例:

输入: [1,2,3,4] 输出: [24,12,8,6]

提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。

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

进阶: 在常数空间复杂度内完成题目,输出数组不被视为额外空间。

解法一:前缀积&后缀积

说明:

  • ​ 前缀积:存着第一个元素到自己的积(不包括自己)
  • ​ 后缀积:存着最后一个元素到自己的积(不包括自己)

分析: 任何一个位置上存着自己左边的所有元素的积再乘以自己右边所有的元素,那么前缀积*后缀积即为我们所求。

var productExceptSelf = function(nums) {
    if (!nums.length) return [];
    if (nums.length === 1) return [1];

    const len = nums.length;
    let l = new Array(len),
        r = new Array(len),
        ret = [];

    l[0] = 1;
    for (let i = 1; i < len; ++i) {
        l[i] = nums[i - 1] * l[i - 1];
    }
    r[len - 1] = 1;
    for (let i = len - 2; i >= 0; --i) {
        r[i] = nums[i + 1] * r[i + 1];
    }
    l.forEach((val, idx, arr) => {
        ret.push(val * r[idx]);
    });
    return ret;
};

解法二(常量空间):前缀积&滚动后缀积常数

  • 只构建前缀积数组。
  • 计算结果时,利用一个滚动变量来维护所需后缀积常数
  • 反过来也是可以的,总之就是一个数组,再维护一个常数即可
const productExceptSelf = nums => {
    const len = nums.length;
    // 定义左累积数组,初始值都为 1
    const resLeft = new Array(len).fill(1);
    for (let i = 1; i < len; i++) {
        // 从i=1开始,作左累积运算
        resLeft[i] = resLeft[i - 1] * nums[i - 1];
    }
    let Right = 1;
    for (let i = len - 1; i >= 0; i--) {
        resLeft[i] = resLeft[i] * Right;
        Right *= nums[i];
    }
    return resLeft;
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤