[2021校招必看之Java版《剑指offer》-51] 构建乘积数组

1、题目描述

  【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];)
  知识点:数组
  难度:☆

2、解题思路

  根据题目描述,如果可以使用除法,就很简单。但是要求不能使用。
  假设:
  left[i] = A[0]*...*A[i-1]
  right[i] = A[i+1]*...*A[n-1]
  所以:
  B[i] = left[i] * right[i]
  这样就避免使用了除法。但是如果对每个B[i], 0<=i<n,都这么求,显然时间复杂度太高。
  把整个结果画到下面图:
在这里插入图片描述
  可知:
  left[i+1] = A[0]*...A[i-1]*A[i]
  right[i+1] = A{i+2]*...*A[n-1]
  于是,
  left[i+1] = left[i] * A[i]
  right[i] = right[i+1] * A[i+1]
  所以,可以先把所有的left[i]求出,right[i]求出。

3、解题代码

package pers.klb.jzoffer.simple;

/**
 * @program: JZoffer
 * @description: 构建乘积数组
 * @author: Meumax
 * @create: 2020-06-17 10:31
 **/
public class ArrayProduct {

    public int[] multiply(int[] A) {

		// 创建数组B
        int[] B = new int[A.length];

		// 初始化第一个元素为1
        B[0] = 1;

  		// 计算 left
        for (int i = 1; i < A.length; i++) {
            B[i] = B[i - 1] * A[i - 1];
        }

        int temp = 1;

		// 计算 right 并乘以 left 得到最终的 B
        for (int j = A.length - 2; j >= 0; j--) {
            temp = temp * A[j + 1];
            B[j] = B[j] * temp;
        }

        return B;
    }
}

  时间复杂度:O(N)
  空间复杂度: O(1)

4、解题心得

  虽然这道题的难度为一颗星,而且我看到题目是的第一反应也是写成下面这样:

package pers.klb.jzoffer.simple;

/**
 * @program: JZoffer
 * @description: 构建乘积数组
 * @author: Meumax
 * @create: 2020-06-17 10:31
 **/
public class ArrayProduct {

    public int[] multiply(int[] A) {
        int length = A.length;
        int[] B = new int[length];
        for(int i=0;i<length;i++){
            B[i] = mulWithoutIndex(A,i);
        }
        return B;
    }

    public int mulWithoutIndex(int[] A,int index){
        int result = 1;

        for(int i = 0;i<A.length;i++){
            if(i == index){
                continue;
            }else{
                result *= A[i];
            }
        }

        return result;
    }
}

  思路极其简单,潜意识就蹦出来了:对于B的每一个元素B[i],计算乘积的时候只需要把对应位置的A[i]跳过去就行了。
  后来一分析自己的这个写法,问题就出在时间复杂度上,自己没有意识到其实自己写出了双层嵌套的for循环,也就是说时间复杂度达到了O(N²),这是不行的,因为有优化空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值