剑指Offer:构建乘积数组

给定一个数组 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[i],每一次计算都要将A中除第 i 个元素外的所有元素相乘,则总的时间复杂度为O(n^2),这种解法不是最好的。

构建矩阵解法

我们将B[i]=A[0] x A[1] x … x A[i-1] x A[i+1] x A[i+2] x… xA[n-1]拆分成两部分A[0] x A[1] x … x A[i-1]和A[i+1] x A[i+2] x… xA[n-1]的乘积。因此,数组B可以用矩阵表示:
这里写图片描述

  • 构建前向乘积数组C[i]=A[0] x A[1] x … x A[i-1],即C[i]=C[i-1] x A[i-1];
  • 构建后向乘积数组D[i]=A[n-1] x A[n-2] x … x A[i+1],即D[i]=D[i+1] x A[i+1];

通过C[i],D[i]来求B[i]:B[i]=C[i] x D[i]
时间复杂度:O(n)

public static int[] multiply(int[] data) {
     if (data == null || data.length < 2) {
          return null;
      }
      int[] result = new int[data.length];
      // result[0]取1
      result[0] = 1;
      for (int i = 1; i < data.length; i++) {
          // 第一步每个result[i]都等于于data[0]*data[1]...data[i-1]
          // 当i=n-1时,此时result[n-1]的结果已经计算出来了
          result[i] = result[i -1] * data[i - 1];
      }
      // tmp保存data[n-1]*data[n-2]...data[i+1]的结果
      int tmp = 1;
      // 第二步求data[n-1]*data[n-2]...data[i+1]
      //result[n-1]的结果已经计算出来,所以从data.length-2开始操作
      for (int i = data.length - 2; i >= 0; i--) {
          tmp *= data[i + 1];
          result[i] *= tmp;
      }
      return result;
  }

猜你喜欢

转载自blog.csdn.net/qq_25343557/article/details/79782601