算法日记:leetcode 238. 除自身以外数组的乘积

这篇博客介绍了如何在不使用除法且时间复杂度为O(n)的情况下解决LeetCode的238题——除自身以外数组的乘积。作者提出利用前缀和后缀数组分别记录每个元素之前和之后的乘积,然后通过遍历数组计算最终结果。文章还探讨了如何通过空间优化进一步减少空间复杂度,将前缀和后缀数组压缩到常数级别,从而达到空间效率的提升。
摘要由CSDN通过智能技术生成

问题描述

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

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

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

来源:力扣(LeetCode)
链接:238 除自身以外数组的乘积

解题思路(思考)

关注点 :(1)不能使用除法

                (2)时间复杂度为O(n):表示只需要相应的一次遍历:就可以获得相应的结果

        基于上述的思考:(不能使用除法) :因此可以将未选择的元素作为枢纽,将其结果进行相应的区分。从而排除掉当前的元素。

若采用暴力的算法,则是双层循环,跳过当前的元素去计算所有的值。这样的算法实现,时间复杂度为O(n²),与题目所要求的O(n)不符合。因此考虑的思路是去多使用额外的空间,实现空间换时间的操作。

        联想到前缀树的思路。使用前缀数组和后缀数组分别记录下当前树的前缀值和后缀值,后面通过遍历数组,进行相应值的相乘,从而得到最终的结果

class Solution {
    public int[] productExceptSelf(int[] nums) {
        // 选择的该数将其值划分成左边界与右边界:能否考虑使用分治的算法进行处理
        //时间的要求为O(N):必然考虑到存在空间换时间的情况
        // 维护两个数组,分别表示前缀和后缀(左边界、右边界)
        int before [] = new int [nums.length];
        int after  [] = new int [nums.length];
        int result [] = new int [nums.length];
        before[0] = 1;
        for(int i = 1;i<nums.length;i++){
            before[i] = before[i-1] * nums[i-1];
        }
        //后缀
        after[nums.length -1] =1;
        for(int i = nums.length-2;i>=0;i--){
            after[i]= nums[i+1]* after[i+1];
        }
        for(int i = 0;i<nums.length;i++){
            result [i] = after[i]* before[i];
        }
        return result;
    }
}

问题优化

能否在空间复杂度的情况下进行相应的优化,去提升相应的空间。(等同于前面156:最大子序乘积的思路:类似于滚动数组的方式实现)

将一维数组(前缀和后缀压缩成常数级别的函数 before 以及after )每次计算后立即进行结果的计算,从而降低相应的空间复杂度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值