22.<tag-数组和前缀和>-lt.238-除自身以外数组的乘积(同剑指 Offer 66. 构建乘积数组) 2

这篇博客介绍了如何高效地计算数组中每个元素除自身以外的乘积。首先提出暴力解法,通过三轮循环计算前缀和后缀乘积,然后结合两者得到结果。接着,优化解法通过两轮循环,在计算前缀乘积的基础上直接更新结果数组,减少了一次遍历。两种解法均针对数组操作进行了优化,提高了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

lt.238-除自身以外数组的乘积

[案例需求]
在这里插入图片描述

[思路分析一, 暴力解法]

  • 由题, 我们可以得出这么一个结论, 那就是每个数nums[i]等于它的前缀乘积 * 后缀乘积
  • 所以我们得出一个很容易想到的解法:
  • 对于原有数组中的每一个数nums[i], 我们借助前缀和写法, 分别使用一个for循环求出nums[i]的前缀之积和后缀之积,分别放在两个数组中
  • 然后再把用一个for循环把这两个数组对应index的求出来即可以得到最终结果数组

[代码实现]

class Solution {
    public int[] productExceptSelf(int[] nums) {
        //每个数等于前一个res*nums[i- 1]/nums[i]
        //前缀的乘积 * 后缀的乘积 = ans
        int len = nums.length;
        // 三轮for循环
         int[] preMulti = new int[len];
         int[] postMulti = new  int[len];

         if(len == 0)return preMulti;
        
         preMulti[0] = 1;
         postMulti[len - 1] = 1;
         for(int i = 1; i < len; i++){
             preMulti[i] = preMulti[i - 1] * nums[ i - 1];
         }

         for(int i = len - 2; i >= 0; i--){
             postMulti[i] = postMulti[i + 1] * nums[i + 1];
         }

         for(int j = 0; j < len; j++){
             preMulti[j] *= postMulti[j];
         }

         return preMulti;
         }
      }

在这里插入图片描述

[思路分析二, 优化解法]

  • 跟思路一基本一致, 只不过是把后缀之积算出来后直接在前缀之积上直接相乘得出结果

[代码实现]

class Solution {
    public int[] productExceptSelf(int[] nums) {
       
        //优化, 两轮for循环
        int[] ans = new int[len];
        int R = 1; //用来存储后缀之积, R就是当前数nums[i] 右边的数的连乘之积
        ans[0] = 1;
        //求出前缀之积
        for(int i = 1; i < len; i++){
            ans[i] = ans[i - 1] * nums[i - 1];
        }

        //求出答案
        //倒序遍历, 因为初始nums[i]为最后一个数, 所以他右边的乘积为1 R=1;
        for(int i = len - 1; i >= 0; i--){
            //
            ans[i] = R * ans[i]; //直接在前缀乘积数组上, 把每个数除了自己的成绩(后缀 * 前缀)重新入到数组
            R = nums[i] * R;// R此时要更改为下一个数(i--)的后缀之积
        }
        return ans;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值