本系列導(dǎo)航:劍指offer(第二版)java實(shí)現(xiàn)導(dǎo)航帖
面試題66:構(gòu)建乘積數(shù)組
題目要求:
給定數(shù)組A[0,1...n-1],求B[0,1...n-1],要求B[i] = A[0]*A[1]...A[i-1]*A[i+1]...A[n-1],不能使用除法。
解題思路:
如果沒(méi)有不能用除法的限制,可以通過(guò)∑A/A[i]求得B[i],同時(shí)要注意A[i]等于0的情況。
既然不能使用除法,那就只好用純乘法計(jì)算。如果每一個(gè)B中的元素都用乘法計(jì)算,那么時(shí)間復(fù)雜度為0(n^2)。
使用純乘法,還有更高效的思路。定義C[i]=A[0]*A[1]...A[i-1],那么C[i]=C[i-1]*A[n-1];定義D[i]=A[i+1]*...A[n-2]*A[n-1],那么D[i] =D[i+1]*A[i+1];因此C[i],D[i]都可以遞推地求出來(lái),且B[i]=C[i]*D[i]。步驟如下:
1.計(jì)算C數(shù)組;
2.依次求得D[0],D[1]...D[n-1],同時(shí)完成B[i]=C[i]\*D[i]的計(jì)算。
如果最終結(jié)果存放于result[]中,第一步的C的值就可以先放到result中,
而D的元素可以存放于一個(gè)變量temp中,通過(guò)result[i] = temp\*result[i]求得B。
時(shí)間復(fù)雜度o(n),由于計(jì)算B必然要申請(qǐng)長(zhǎng)度為n的空間,除此之外,該方法僅申請(qǐng)了幾個(gè)變量,空間復(fù)雜度o(1)。
package chapter6;
/**
* Created with IntelliJ IDEA
* Author: ryder
* Date : 2017/8/21
* Time : 8:45
* Description:構(gòu)建乘積數(shù)組
**/
public class P313_ConstructArray {
public static int[] multiply(int[] data){
if(data==null||data.length<2)
return null;
int[] result = new int[data.length];
//求得數(shù)組C,存于result中
result[0] = 1;
for(int i=1;i<result.length;i++)
result[i] = result[i-1]*data[i-1];
//先求得數(shù)組D中元素,再與C中元素相乘,存于result中
int temp = 1;
for(int i=data.length-2;i>=0;i--){
//數(shù)組D中的元素值
temp = temp * data[i+1];
//計(jì)算B[i]=C[i]*D[i]
result[i] = result[i] * temp;
}
return result;
}
public static void main(String[] args){
int[] data = new int[]{1,2,3,4,5};
int[] result = multiply(data);
for(int i=0;i<result.length;i++){
System.out.print(result[i]);
System.out.print(" ");
}
}
}
運(yùn)行結(jié)果
120 60 40 30 24