【JS每日一算法:剑指Offer系列】🟨155.除自身以外数组的乘积(双数组、单数组)

81 阅读3分钟

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

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

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

 

示例 1:

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

示例 2:

输入: nums = [-1,1,0,-3,3]
输出: [0,0,9,0,0]

 

提示:

  • 2 <= nums.length <= 105
  • -30 <= nums[i] <= 30
  • 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在  32 位 整数范围内  

进阶:你可以在 O(1) 的额外空间复杂度内完成这个题目吗?( 出于对空间复杂度分析的目的,输出数组 不被视为 额外空间。)

 

题解:

个人博客

更多JS版本题解点击链接关注该仓库👀

/**
 * @description: 双数组  TC:O(n)  SC:O(n)
 * @author: JunLiangWang
 * @param {*} nums 给定数组
 * @return {*}
 */
function twoArray(nums) {
    /**
     * 本方案采用双数组的方式,定义左右两数组leftArray,rightArray长度与
     * nums一致。
     * 
     * 对于两数组索引i处元素:
     * 
     * 左数组i处元素leftArray[i]为nums的[0至i-1]的乘积
     * 右数组i处元素rightArray[i]为nums的[i+1,nums.length-1]的乘积
     * 
     * 除 nums[i] 之外其余各元素的乘积则为:leftArray[i]*rightArray[i]
     * 
     * 示例:     nums = [1,2,3,4]
     *       leftArray = [1,1,2,6]
     *       rightArray= [24,12,4,1]
     *             结果= [24,12,8,6]
     */


    //定义左右两数组leftArray,rightArray长度与nums一致。
    let leftArray = new Array(nums.length),
        rightArray = new Array(nums.length),
        outArray = new Array(nums.length);
    // 初始化左数组[0]为1
    leftArray[0] = 1;
    // 初始化右数组最后一个元素为1
    rightArray[nums.length - 1] = 1;

    let index = 0;
    // 遍历计算左数组元素值:
    // 左数组i处元素leftArray[i]为nums的[0至i-1]的乘积
    while (index < nums.length - 1) {
        leftArray[index + 1] = leftArray[index] * nums[index]
        index++;
    }
    // 遍历计算右数组元素值:
    // 右数组i处元素rightArray[i]为nums的[i+1,nums.length-1]的乘积
    index = nums.length - 1;
    while (index > 0) {
        rightArray[index - 1] = rightArray[index] * nums[index]
        index--;
    }
    // 遍历计算结果:
    // 除 nums[i] 之外其余各元素的乘积则为:leftArray[i]*rightArray[i]
    index = 0;
    while (index < nums.length) {
        outArray[index] = leftArray[index] * rightArray[index]
        index++;
    }
    // 返回结果
    return outArray;
}


/**
 * @description: 单数组 TC:O(n)  SC:O(1)
 * @author: JunLiangWang
 * @param {*} nums 给定数组
 * @return {*}
 */
function singleArray(nums) {
    /**
     * 我们可以对上述方案进行优化,使用一个数组即可完成
     */


    //定义结果数组长度与nums一致。
    let outArray = new Array(nums.length);
    // 初始化数组[0]为1
    outArray[0] = 1;

    // 遍历计算左数组元素值:
    // 左数组i处元素outArray[i]为nums的[0至i-1]的乘积
    let index = 0;
    while (index < nums.length - 1) {
        outArray[index + 1] = outArray[index] * nums[index]
        index++;
    }
    index = nums.length - 1;
    // 定义变量记录nums的[i+1,nums.length-1]的乘积
    let rightResult = 1;

    // 遍历计算右数组元素值并直接计算结果
    while (index >= 0) {
        // 除 nums[i] 之外其余各元素的乘积则为:outArray[i]*rightResult
        outArray[index] *= rightResult
        //更新nums的[i+1,nums.length-1]的乘积
        rightResult *= nums[index]
        index--;
    }
    // 返回结果
    return outArray
}

来源:力扣(LeetCode)