Solution from EPI book
O(N) time and O(N) space
public static int findBiggestProductNMinusOneProduct(List<Integer> A) {
// Build forward product L, and backward product R.
List<Integer> L = new ArrayList<>(A.size());
List<Integer> R = new ArrayList<>(A.size());
fill(L, A.size(), 0);
fill(R, A.size(), 0);
partialSum(A.iterator(), L.listIterator(), BinaryOperators.MULTIPLIES);
partialSum(revListIterator(A), revListIterator(R),
BinaryOperators.MULTIPLIES);
// Find the biggest product of (n - 1) numbers.
int maxProduct = Integer.MIN_VALUE;
for (int i = 0; i < A.size(); ++i) {
int forward = i > 0 ? L.get(i - 1) : 1;
int backward = i + 1 < A.size() ? R.get(i + 1) : 1;
maxProduct = max(maxProduct, forward * backward);
}
return maxProduct;
}
O(N) time and O(1) space
public static int findBiggestNMinusOneProduct(int[] A) {
int zeroCount = 0, posCount = 0, negCount = 0;
int zeroIdx = -1, sNegIdx = -1, bNegIdx = -1, sPosIdx = -1;
for (int i = 0; i < A.length; ++i) {
if (A[i] < 0) {
++negCount;
if (sNegIdx == -1 || A[i] < A[sNegIdx]) {
sNegIdx = i;
}
if (bNegIdx == -1 || A[bNegIdx] < A[i]) {
bNegIdx = i;
}
} else if (A[i] == 0) {
zeroIdx = i;
++zeroCount;
} else { // A[i] > 0.
++posCount;
if (sPosIdx == -1 || A[i] < A[sPosIdx]) {
sPosIdx = i;
}
}
}
// Try to find a number whose elimination could maximize the product of
// the remaining (n - 1) numbers.
int x; // Stores the idx of eliminated one.
if (zeroCount >= 2) {
return 0;
} else if (zeroCount == 1) {
if ((negCount & 1) > 0) {
return 0;
} else {
x = zeroIdx;
}
} else {
if ((negCount & 1) > 0) { // Odd number negative.
x = bNegIdx;
} else { // Even number negative.
if (posCount > 0) {
x = sPosIdx;
} else {
x = sNegIdx;
}
}
}
int product = 1;
for (int i = 0; i < A.length; ++i) {
if (i != x) {
product *= A[i];
}
}
return product;
}
O(N) time and O(N) space
public static int findBiggestProductNMinusOneProduct(List<Integer> A) {
// Build forward product L, and backward product R.
List<Integer> L = new ArrayList<>(A.size());
List<Integer> R = new ArrayList<>(A.size());
fill(L, A.size(), 0);
fill(R, A.size(), 0);
partialSum(A.iterator(), L.listIterator(), BinaryOperators.MULTIPLIES);
partialSum(revListIterator(A), revListIterator(R),
BinaryOperators.MULTIPLIES);
// Find the biggest product of (n - 1) numbers.
int maxProduct = Integer.MIN_VALUE;
for (int i = 0; i < A.size(); ++i) {
int forward = i > 0 ? L.get(i - 1) : 1;
int backward = i + 1 < A.size() ? R.get(i + 1) : 1;
maxProduct = max(maxProduct, forward * backward);
}
return maxProduct;
}
O(N) time and O(1) space
public static int findBiggestNMinusOneProduct(int[] A) {
int zeroCount = 0, posCount = 0, negCount = 0;
int zeroIdx = -1, sNegIdx = -1, bNegIdx = -1, sPosIdx = -1;
for (int i = 0; i < A.length; ++i) {
if (A[i] < 0) {
++negCount;
if (sNegIdx == -1 || A[i] < A[sNegIdx]) {
sNegIdx = i;
}
if (bNegIdx == -1 || A[bNegIdx] < A[i]) {
bNegIdx = i;
}
} else if (A[i] == 0) {
zeroIdx = i;
++zeroCount;
} else { // A[i] > 0.
++posCount;
if (sPosIdx == -1 || A[i] < A[sPosIdx]) {
sPosIdx = i;
}
}
}
// Try to find a number whose elimination could maximize the product of
// the remaining (n - 1) numbers.
int x; // Stores the idx of eliminated one.
if (zeroCount >= 2) {
return 0;
} else if (zeroCount == 1) {
if ((negCount & 1) > 0) {
return 0;
} else {
x = zeroIdx;
}
} else {
if ((negCount & 1) > 0) { // Odd number negative.
x = bNegIdx;
} else { // Even number negative.
if (posCount > 0) {
x = sPosIdx;
} else {
x = sNegIdx;
}
}
}
int product = 1;
for (int i = 0; i < A.length; ++i) {
if (i != x) {
product *= A[i];
}
}
return product;
}