面试题66:构建乘积数组
题目:给定一个数组 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:
- 以{1, 2, 3, 4, 5}为例
- 第一次可以看做 1 和 2×3×4×5×1 相乘
- 第二次可以看做 1×1 和 3×4×5×1 相乘
- 第三次可以看做 1×1×2 和 4×5×1 相乘
- 第四次可以看做 1×1×2×3 和 5×1 相乘
- 第五次可以看做 1×1×2×3×4 和 1 相乘
- 左边用一个数组保存起来,右边用一个数组保存起来。最后的结果就是两个数组中的元素对应相乘。
代码实现:
package Question66;
import java.util.Arrays;
public class T01 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(solve(arr)));
}
public static int[] solve(int[] arr) {
if(arr == null || arr.length == 0) return new int[0];
int[] front = new int[arr.length];
int[] post = new int[arr.length];
for(int i = 0; i < arr.length; i++) {
if(i == 0) {
front[i] = 1;
post[arr.length - i - 1] = 1;
} else {
front[i] = front[i-1] * arr[i-1];
post[arr.length - i - 1] = post[arr.length - i] * arr[arr.length - i];
}
}
int[] result = new int[arr.length];
for(int i = 0; i < arr.length; i++) result[i] = front[i] * post[i];
return result;
}
}
思路2:
- 其实不用建立那两个数组
- 第一遍从前往后遍历,乘上本来在第一个数组中的数(不用建立第一个数组,在遍历的过程中可以直接获得)
- 第二遍从后往前遍历,乘上本来在第二个数组中的数(不用建立第二个数组,在遍历的过程中可以直接获得)
代码实现:
package Question66;
import java.util.Arrays;
public class T02 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
System.out.println(Arrays.toString(solve(arr)));
}
public static int[] solve(int[] arr) {
if(arr == null || arr.length == 0) return new int[0];
int[] result = new int[arr.length];
for(int i = 0, cur = 1; i < arr.length; i++) {
result[i] = cur;
cur *= arr[i];
}
for(int i = arr.length - 1, cur = 1; i >= 0; i--) {
result[i] *= cur;
cur *= arr[i];
}
return result;
}
}