【剑指Offer】JZ51 构建乘积数组 (有点懵)

题目描述
给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)

理解1、通过 B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]
知道了不会乘上自己对应的那个值A[i]
可以分为两部分
●从左往右 B[i]=A[0]A[1]…A[i-1]
●从右往左 B[i]=A[i+1]
…*A[n-1]

最后两个 B[i]相乘可得B[n]。

代码1:

import java.util.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
        int len = A.length;
        int[] B = new int[len];
        int muty = 1;
        int my = 1;
        //Left ->right
       // for(int i=0;i<len-1;i++){
       //     muty*=A[i++];
       //     B[i]=muty;
       // }
            for(int i=0;i<len;muty*=A[i++]){
            B[i]=muty;
        }
         
         for(int i = len - 1;i >= 0;i--){
                muty*=A[i--];
                B[i] *= muty;
            }
            //for(int j = len - 1;j >= 0;j--){
           //     my*=A[j--];
           //     B[j] *= my;
          //  }
             
        return B;
         
    }
}

提交出现异常,百度搜索是这样描述的:

JAVA API:
public class ArrayIndexOutOfBoundsExceptionextends IndexOutOfBoundsException
用非法索引访问B数组时抛出的异常。如果索引为负或大于zhi等于数组大小,则该索引为非法索引。
也就是说角标异常!可能的原因是使用的角标大于等于数组的长度或为负数!在这里插入图片描述

修改代码1.2:

import java.util.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
        int length = A.length;
        int[] b = new int[length];
       
    
        int ret=1;
        for(int i=0;i<length;i++){
            ret*=A[i];
            b[i]=ret;
        }
        ret=1;
        for(int i=length-1;i>=0;i--){
            ret*=A[i];
            b[i]*=ret;
        }
        return b;
    }
}

起码输出值了,哈哈哈哈。看输出结果是反向增大的,标准输出是反向减小,我特么…
在这里插入图片描述
在这里插入图片描述

***> 欢迎大哥哥大姐姐们指导下 为啥 代码1.2 值不一样呀,我懵了QAQ、***

再修改1.3:

//修改
import java.util.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
        int length = A.length;
        int[] b = new int[length];
       
    
        int ret=1;
        for(int i=0;i<length;ret*=A[i++]){ //把ret*=A[i++]放在for循环里面
            b[i]=ret;
        }
        ret=1;
        for(int i=length-1;i>=0;ret*=A[i--]){ //同上
            b[i]*=ret;
        }    
        return b;
    }
}

修改通过,我个人觉得可能是把ret*=A[i++]放在for循环里面,时间复杂度缩小了,少计算了一步i++,

理解2
构建矩阵
B[i]的值可以看作下图的矩阵中每行的乘积。
在这里插入图片描述
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。

代码2.1

import java.util.ArrayList;
public class Solution {
    public int[] multiply(int[] A) {
        int length = A.length;
        int[] B = new int[length];
        if(length != 0 ){
            B[0] = 1; //必不可少,因为最后B【0】数值也要算进去,否则会抛出java.lang.ArrayIndexOutOfBoundsException: -1
            //计算下三角连乘
            for(int i = 1; i < length; i++){
                B[i] = B[i-1] * A[i-1];
            }
            int muty = 1;
            //计算上三角
            for(int j = length-2; j >= 0; j--){
                muty *= A[j+1];
                B[j] *= muty;
            }
        }
        return B;
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值