力扣238.除自身以外数组的乘积 & 剑指offer 51.构建乘积数组

力扣238.除自身以外数组的乘积 & 51.构建乘积数组

题目描述

给定一个数组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];)

题意分析:

B[i]的意义是A数组不包括i位置的所有乘积,分为 i左边的元素乘积和 i右边的所有元素乘积。第一个for计算i左边的乘积,第二个for计算右边的。初始化B[0]=1,是因为0左边没有元素,所以乘积为1。

思路一:

剑指的思路:
B[i]的值可以看作下图的矩阵中每行的乘积。
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
复杂度为O(n)
 1 import java.util.ArrayList;
 2 public class Solution {
 3     public int[] multiply(int[] A) {
 4         if(A == null){
 5             return null;
 6         }
 7         int[] B = new int[A.length];
 8         int len = A.length;
 9         if(len != 0){
10             B[0] = 1;
11             // 计算下三角连乘
12             for(int i = 1; i < len; i++){
13                 B[i] = B[i - 1] * A[i - 1];
14             }
15             // 计算上三角
16             int res = 1;
17             for(int i = len - 2; i >= 0; i--){
18                 res *= A[i + 1];
19                 B[i] *= res;
20             }
21         }
22         return B;
23        
24     }
25 }

 力扣测试时间为3ms, 空间为48.3MB

复杂度分析:

时间复杂度:遍历了两次数组,所以时间复杂度为O(n)

空间复杂度:新建了一个结构数组B, 所以空间复杂度为O(n)

思路二:

双重循环,复杂度为O(n^2)

 1 import java.util.ArrayList;
 2 public class Solution {
 3     public int[] multiply(int[] A) {
 4         if(A == null || A.length == 0){
 5             return null;
 6         }
 7         int[] B = new int[A.length];
 8        // 两个循环
 9         for(int i = 0; i < A.length; i++){
10             B[i] = 1;
11             for(int j = 0; j < i; j++){
12                 B[i] *= A[j];
13             }
14             for(int j = i + 1; j < A.length; j++){
15                 B[i] *= A[j];
16             }
17         }
18         return B;
19     }
20 }

 

posted @ 2020-04-03 22:00  Lucky小黄人^_^  阅读(156)  评论(0编辑  收藏  举报