[算法]不包含本位置值的累乘数组
题目:
给定一个整型数组,返回不包含本位置的累乘数组。
例如:arr=[2,3,1,4],返回[12,8,24,6],即除自己外,其他位置的类乘。
要求:
1.时间复杂度为O(N).
2.除需要返回的结果数组之外,额外空间复杂度为O(1).
使用除法:
结果数组记为res,所有数的乘积记为all。如果数组中不含0,则设置res[i]=all/arr[i]。如果数组中有一个0,对唯一的arr[i]==0的位置令res[i]=all,其他位置都是0。如果数组中0的数量大于1,那么res所有位置上的值都是0。
public static int[] product1(int[] arr) {if (arr == null || arr.length < 2) {return null;}int count = 0;
int all = 1;
for (int i = 0; i != arr.length; i++) {if (arr[i] != 0) {
all *= arr[i];} else {
count++;}}int[] res = new int[arr.length];if (count == 0) {
for (int i = 0; i != arr.length; i++) {res[i] = all / arr[i];}}if (count == 1) {
for (int i = 0; i != arr.length; i++) {if (arr[i] == 0) {
res[i] = all;}}}return res;
}
不使用除法:
1.生成两个长度和arr一样的新数组lr[]和rl[],lr[i]=arr[0…i],rl[i]=arr[i…N-1]。
2.res[i]=lr[i-1]*rl[i+1]
3.res[0]=rl[1],res[N-1]=lr[N-2]
这里又额外使用了两个数组,可以通过res数组复用的方式省略掉这两个数组,先把res数组作为辅助计算的数组,然后把res调整成结果数组返回。
public static int[] product2(int[] arr) {if (arr == null || arr.length < 2) {return null;}int[] res = new int[arr.length];res[0] = arr[0];for (int i = 1; i < arr.length; i++) {res[i] = res[i - 1] * arr[i];}int tmp = 1;
for (int i = arr.length - 1; i > 0; i--) {res[i] = res[i - 1] * tmp;tmp *= arr[i];}res[0] = tmp;return res;