Product of Array Exclude Itself
25% Accepted
Given an integers array A.
Define B[i] = A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1],
calculate B WITHOUT divide operation.
Have you met this question in a real interview? Yes
Example
For A = [1, 2, 3], return [6, 3, 2].
Tags Expand
- Forward-Backward Traversal
- LintCode Copyright
暴力 O(n2) 解法, 并没有什么用
public class Solution {
/**
* @param A: Given an integers array A
* @return: A Long array B and B[i]= A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1]
*/
public ArrayList<Long> productExcludeItself(ArrayList<Integer> A) {
// write your code
ArrayList<Long> result = new ArrayList<Long>();
for (int i = 0; i < A.size(); i++) {
long B = 1;
for (int j = 0; j < A.size(); j++) {
if (j != i) {
B = B * A.get(j);
}
}
result.add(B);
}
return result;
}
}
O(n)解法
- 前后夹击,空间换时间,把前边每一个product算出来,后边每一个算出来
- left_product[i] 表示i前边的数的积
- right_product[i] 表示i后边的数的积
- 再一个for循环,去给result添加值
- 设置left right的时候 定义先设置好,这样好考虑边界条件
- 比如left[i] 表示 前i-1个数的乘积 right[i] 后i+1个数的乘积
public class Solution {
/**
* @param A: Given an integers array A
* @return: A Long array B and B[i]= A[0] * ... * A[i-1] * A[i+1] * ... * A[n-1]
*/
public ArrayList<Long> productExcludeItself(ArrayList<Integer> A) {
// write your code
if ( A == null || A.size() == 0) {
return null;
}
ArrayList<Long> result = new ArrayList<Long>();
long[] left_product = new long[A.size()];
long[] right_product = new long[A.size()];
left_product[0] = 1;
for (int i = 1; i < A.size(); i++) {
left_product[i] = left_product[i - 1] * A.get(i - 1);
}
right_product[A.size() - 1] = 1;
for (int i = A.size() - 2; i >= 0; i--) {
right_product[i] = right_product[i + 1] * A.get(i + 1);
}
for (int i = 0; i < A.size(); i++) {
result.add(left_product[i] * right_product[i]);
}
return result;
}
}
Leetcode
public class Solution {
public int[] productExceptSelf(int[] nums) {
if (nums == null || nums.length == 0) {
return new int[0];
}
int len = nums.length;
int[] left = new int[len];
int[] right = new int[len];
left[0] = nums[0];
right[len - 1] = nums[len - 1];
for (int i = 1; i < len; i++) {
left[i] = left[i - 1] * nums[i];
}
for (int i = len - 2; i >= 0; i--) {
right[i] = right[i + 1] * nums[i];
}
int[] result = new int[len];
result[0] = right[1];
result[len - 1] = left[len - 2];
for (int i = 1; i < len - 1; i++) {
result[i] = left[i - 1] * right[i + 1];
}
return result;
}
}
空间优化
- 左边过一遍,先留着左边相乘的值
- 再过一遍右边,从头开始计算右边相乘的值,存在end里
public class Solution {
public int[] productExceptSelf(int[] nums) {
if (nums == null || nums.length == 0) {
return new int[0];
}
int len = nums.length;
int[] result = new int[len];
result[0] = 1;
for (int i = 1; i < len; i++) {
result[i] = result[i - 1] * nums[i - 1];
}
int end = 1;
for (int i = len - 2; i >= 0; i--) {
end *= nums[i + 1];
result[i] *= end;
}
return result;
}
}