劍指Offer_#66_構建乘積陣列
阿新 • • 發佈:2020-07-29
劍指Offer_#66_構建乘積陣列
劍指offerContents
題目
給定一個數組 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]。不能使用除法。
示例:
輸入: [1,2,3,4,5]
輸出: [120,60,40,30,24]
提示:
所有元素乘積之和不會溢位 32 位整數
a.length <= 100000
思路分析
用除法的解法
本題難點在於題目限制不準用除法,如果可以用除法的話,很好解決。
- 計算
A[]
中所有元素乘積product
- 遍歷一遍
A[]
陣列,B[i] = product / A[i]
不用除法的解法
將每個B[i]
的表示式寫出來,就是下面表格的樣子。
我們發現可以每一行被1分為左右兩個部分,或者說上三角部分和下三角部分。
我們可以分別計算每一行當中1的左邊部分,1的右邊部分,然後將兩部分相乘,就得到對應的B[i]
。
編碼技巧: 計算上下三角部分的乘積時,非常容易弄錯,最好先在紙上畫出上述表格,然後對照著寫,不然容易亂。
解答
解答1:較直觀的寫法
這個程式碼比較直觀,可讀性好,但是空間複雜度稍高,藉助2個額外的陣列。空間複雜度為O(n)。
class Solution {
public int[] constructArr(int[] a) {
int n = a.length;
if(n == 0) return new int[0];
int[] up = new int[n];//上三角部分乘積
int[] down = new int[n];//下三角部分乘積
//上三角從最下邊的1開始迭代
up[n - 1] = 1;
//下三角從最上邊的1開始迭代
down[0] = 1;
//計算上三角部分,由下到上累乘
for(int i = n - 2;i >= 0;i--){
up[i] = up[i + 1] * a[i + 1];
}
//計算下三角部分,由上到下累乘
for(int i = 1; i <= n - 1;i++){
down[i] = down[i - 1] * a[i - 1];
}
//最後將上下三角部分逐位對應相乘,得到的新陣列就是結果B[0...n-1]
for(int i = 0;i <= n - 1;i++){
up[i] *= down[i];
}
return up;
}
}
複雜度分析
時間複雜度: O(n)
空間複雜度: O(n)
解答2:優化空間複雜度
少用了一個數組,可讀性稍微差點。因為b
是返回值,所以不算在空間複雜度內。
class Solution {
public int[] constructArr(int[] a) {
if(a.length == 0) return new int[0];
int[] b = new int[a.length];
b[0] = 1;
//將上三角中的數字乘入b[i]
for(int i = 1; i <= b.length - 1;i++){
b[i] = b[i - 1] * a[i - 1];
}
//將下三角中一行的數字相乘,記作tmp,然後乘入b[i]
int tmp = 1;
for(int i = a.length - 2;i >= 0;i--){
tmp *= a[i + 1];
b[i] *= tmp;
}
return b;
}
}
複雜度分析
時間複雜度: O(n)
空間複雜度: O(1)