1.题目
2.思路
这个题的唯一限制为不能使用除法!!!--如果可以使用除法,直接计算所有的成绩mul 除以 a[i]就可以了,显然没有这么简单。
然后看这个题需要计算多个数乘在一起,很容易想到前缀和的思想,这里应用为前缀积,可以直接计算a[i]前半部分的乘积a[0] * a[1] * a[2] * ...*a[i-1],然后发现还少后半部乘积,自己卡住了,10分钟...........
一看答案,再反向前缀积就好了。。。a[n- 1] * a[n -2] * ...* a[i +1]
前缀和 ---遍历三次--O(N) - 2ms
class Solution {
public int[] constructArr(int[] a) {
int n = a.length;
if(n == 0) return new int[]{};
int[]ans = new int[n];
long[]preMul = new long[n + 1];
preMul[0] = 1;
for(int i = 1 ; i <= n; i++){
// 从前往后计算
preMul[i] = preMul[i - 1] * a[i - 1];
// System.out.println(preMul[i]);
// 等于 0 怎么办
}
long[]backMul = new long[n + 1];
backMul[0] = 1;
for(int i = 1; i <= n ; i++){
backMul[i] = backMul[i - 1] * a[n - i]; //从后往前计算
// System.out.println(backMul[i]+">>>");
}
for(int i = 0 ; i < n; i++){
long t1 = 1;
if(i != 0) t1 = preMul[i];
long t2 = 1;
if(i != n - 1) t2 = backMul[n - i - 1];
ans[i] = (int)(t1 * t2);
}
return ans;
}
}
前缀和 ---遍历两次--O(N) - 1ms【还可以只遍历一次就解决的】
class Solution {
public int[] constructArr(int[] a) {
int n = a.length;
if(n == 0) return new int[]{};
int[]ans = new int[n];
long[]preMul = new long[n + 1];
preMul[0] = 1;
// for(int i = 1 ; i <= n; i++){
// // 从前往后计算
// preMul[i] = preMul[i - 1] * a[i - 1];
// // System.out.println(preMul[i]);
// // 等于 0 怎么办
// }
int[]backMul = new int[n + 1];
backMul[0] = 1;
for(int i = 1; i <= n ; i++){
backMul[i] = backMul[i - 1] * a[n - i]; //从后往前计算
// System.out.println(backMul[i]+">>>");
}
int t1 = 1;
for(int i = 0 ; i < n; i++){
int t2 = 1;
if(i != 0) t1 *= a[i - 1];
if(i != n - 1) t2 = backMul[n - i - 1];
ans[i] = t1 * t2;
}
return ans;
}
}
3.结果