LeetCode 热题 100——普通数组——除自身以外数组的乘积

18.除自身以外数组的乘积

题目描述

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

题目数据 保证 数组 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 <= numsi <= 30

输入 保证 数组 answeri 在 32 位 整数范围内

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

求解

这道题第一个思路 就是使用 除法,算一个全部乘积,然后遍历数组,除以i位置的元素,但是存在为0的情况,使用除法就会出问题。

(1)前缀乘积+后缀乘积

使用 两个数组分别计算得到 前缀乘积和后缀乘积 数组,遍历的时候,除去i 位置的前缀和后缀乘积相乘即可。

js 复制代码
var productExceptSelf = function(nums) {
    let len = nums.length
    // 定义两个数组,分别存放 前缀乘积、后缀乘积 (类似 前缀和)
    let preArr = new Array(len)
    let sufArr = new Array(len)
    let preMul = 1
    for (let i = 0; i < len; i++) {
        preMul *= nums[i]
        preArr[i] = preMul
    }
    let sufMul = 1
    for (let i = len - 1; i >= 0; i--) {
        sufMul *= nums[i]
        sufArr[i] = sufMul
    }
    for (let i = 0; i < len; i++) {
        if (i === 0) {
            nums[i] = sufArr[i + 1]
        } else if (i === len - 1) {
            nums[i] = preArr[i - 1]
        } else {
            nums[i] = preArr[i - 1] * sufArr[i + 1]
        }
    }
    return nums
};

(2)优化

主要是优化 空间复杂度

js 复制代码
var productExceptSelf = function(nums) {
    // 优化空间复杂度
    let len = nums.length
    // 定义两个数组,分别存放 前缀乘积、后缀乘积 (类似 前缀和)
    let ans = new Array(len)

    // ans[i] 表示 索引i左侧所有元素的乘积
    // 索引为 0 的元素左侧没有元素,ans[0] = 1
    ans[0] = 1
    for (let i = 1; i < len; i++) {
        ans[i] = ans[i - 1] * nums[i - 1]
    }

    // 定义R:为右侧所有元素的乘积
    let R = 1
    for (let i = len - 2; i >= 0; i--) {
        R *= nums[i + 1]
        ans[i] = ans[i] * R
    }
    return ans
};

这样就不用计算两个数组,时间复杂度不变,并且省出了一半的空间。

相关推荐
淡海水8 小时前
07-04-并发-ConcurrentBag-T-工作窃取WorkStealing算法
开发语言·算法·c#·bag·concurrent·workstealing
leobertlan8 小时前
好玩系列:训练一个神经网络模型指导小孩玩游戏2-大局观教练
算法
Tisfy9 小时前
LeetCode 3876.构造奇偶一致的数组 II:三种情况分类讨论(其实还是脑筋急转弯)
算法·leetcode·题解·脑筋急转弯
乐迪信息10 小时前
智慧港口船舶AI算法实现在线状态监测
大数据·人工智能·深度学习·算法·计算机视觉
kiracrimson11 小时前
从缓存的角度看链表与线性表的差异
数据结构·链表·缓存
木井巳11 小时前
【BFS/DFS 解决 FloodFill 算法】太平洋大西洋水流问题
java·算法·leetcode·深度优先·广度优先·宽度优先·推荐算法
心抵鹊12 小时前
归并排序之翻转对(hard)
数据结构·算法
白山编程大哥12 小时前
Java 集合算法:从排序、查找到底层原理的实战指南
java·python·算法
shehuiyuelaiyuehao12 小时前
算法34,位运算符操作,总结
算法
Navigator_Z12 小时前
LeetCode //C - 1224. Maximum Equal Frequency
c语言·算法·leetcode