Problem Statement
Pattern: Pattern Prefix Array
Naive Solution
public int[] productExceptSelf(int[] nums) {
int prod = 1, zero = 0;
for (int num : nums)
if (num == 0) zero++;
else prod *= num;
for (int i = 0; i < nums.length; i++) {
switch (zero) {
case 0: {
nums[i] = divide(prod, nums[i]);
break;
}
case 1: {
if(nums[i] == 0) nums[i] = prod;
else nums[i] = 0;
break;
}
default: {
nums[i] = 0;
break;
}
}
}
return nums;
}
// count the no. of times b can be subtracted from a
private int divide(int a, int b) {
// get absolute a b
int sign = ((a > 0 && b > 0) || (a < 0 && b < 0)) ? 1 : -1;
a = Math.abs(a);
b = Math.abs(b);
// edge cases
if(a == 0) return 0;
if(b == 1 || b == 0) return a*sign;
// init
int B = b, pow = 1, count = 0;
// get the highest power of b less than a
while(a >= B*b) {
pow++;
B *= b;
}
while (a!=0) {
// get correct pow
while(a < B)
B = (int) Math.pow(b, --pow);
// divide
a -= B;
// update count
count += Math.pow(b, pow-1);
//System.out.printf("Pow: %d Count: %d\n", pow, count);
}
return count * sign;
}
Notes
- Works perfectly, but TLE if Input is too large 🤷♂️
- Basically we diviide how division works, except we increment decrement denominator in powers of itself
3 -> 3, 9, 27, 81
- First increment to find largest power
- Then as we start dividing (substracting from a) we reduce power when needed.
- We update how many times we had to to remove
b
froma
in the variablecount
Smart Solution
public int[] productExceptSelf(int[] nums) {
// init result array
int n = nums.length;
int[] res = new int [n];
// convert res into prefix product array
res[0] = 1;
for (int i = 1; i < n ; i++) {
res[i] = res[i-1]*nums[i-1];
}
// instead of suffix array we use suffix variable suffixProd
int suffixProd = 1;
// last el has no suffix i = n-2
for (int i = n-2; i >= 0; i--) {
// get suffix product
suffixProd *= nums[i+1];
res[i] *= suffixProd;
}
return res;
}
Notes
- Simply put
- create 2 arrays
- prefix array : store the product of all the elements BEFORE i at
prefix[i]
- suffix array : store the product of all the elements AFTER i at
suffix[i]
- prefix array : store the product of all the elements BEFORE i at
- so
nums[i]
would simply beprefix[i] * suffix[i]
- that is the product of all the numbers before and afteri
- since we can’t have 2 extra arrays for storing the prefix and suffix separately
- we store the prefix in the result array
res
, and multiply it with the current suffixsuffixProd
when we are moving backwards!!
- we store the prefix in the result array
- create 2 arrays
res
is the result array so it does not count as extra space. It is still constant space. If they had asked for an in-place solution, only then would we have been unable to create the result array