1、题目论述
给定一个数组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];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
2、题目分析
直接看图:上三角和下三角
B数组的每一个元素为A数组的每一行的乘积B数组的第i个元素在A数组中的下标对应的元素为1
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
3、代码实现
import java.util.ArrayList;
public class Solution {
public int[] multiply(int[] A) {
/*
给定一个数组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];)
对于A长度为1的情况,B无意义,故而无法构建,因此该情况不会存在。
*/
/*
B[0] 1 A[1] A[2] A[3] ...A[n-1]
B[1] A[0] 1 A[2] A[3] ... A[n-1]
B[2] A[0]A[1] 1 A[n-1]
B[3] A[0] 1 A[n-1]
B[4]
B[n-1] 1
*/
int length = A.length;
//定义数组B
int[] B = new int[length];
if(length != 0){
B[0] = 1;
//计算上三角的值
for(int i = 1;i < length;i++){
B[i] = B[i-1]*A[i-1];
}
int temp = 1;
// length-1是数组最后一项,length-2是数组的倒第二项
for(int j = length-2;j >= 0;j--){
//A[j+1]是数组的倒第一项
temp = temp*A[j+1];
//B数组的倒第二项*temp
B[j] = B[j]*temp;
}
}
return B;
}
}
4、总结
每一个B[i]是一个A[0]——>A[n-1]的乘积,在A[i]的位置上A[i]的值为1分别计算上三角和上三角的值,返回的是B数组
最近在牛客上看别人拿到Offer,笔试的算法题剑指Offer类似的多,建议多刷几遍,还有leetCode的算法题,热门的前几百道。
做技术,实属不易。今天买了《深入理解Java虚拟机》,《数据结构与算法分析》,《Java并发技术实战》,《head first设计模式》,打算入Java坑了。
每天进步一点点,change yourself now !
量变到质变是个漫长的过程,相信2年后硕士毕业会给自己带来惊喜!