Problem: Product of Array Except Self
Given an integer array nums
, return an array answer
such that answer[i]
is equal to the product of all the elements of nums
except nums[i]
.
- You must solve it without using division.
- Your solution should run in O(n) time.
- The product of any prefix or suffix of
nums
is guaranteed to fit in a 32-bit integer.
Example 1:
Input:
nums = [1, 2, 3, 4]
Output:
[24, 12, 8, 6]
Explanation:
answer[0] = 2 * 3 * 4 = 24
answer[1] = 1 * 3 * 4 = 12
answer[2] = 1 * 2 * 4 = 8
answer[3] = 1 * 2 * 3 = 6
Example 2:
Input:
nums = [-1, 1, 0, -3, 3]
Output:
[0, 0, 9, 0, 0]
Explanation:
answer[0] = 1 * 0 * -3 * 3 = 0
answer[1] = -1 * 0 * -3 * 3 = 0
answer[2] = -1 * 1 * -3 * 3 = 9
answer[3] = -1 * 1 * 0 * 3 = 0
answer[4] = -1 * 1 * 0 * -3 = 0
Constraints:
2 <= nums.length <= 10^5
-30 <= nums[i] <= 30
- The product of any prefix or suffix of
nums
is guaranteed to fit in a 32-bit integer.
Follow-up:
Can you solve the problem in O(1) extra space complexity? (The output array does not count as extra space for space complexity analysis.)
Algorithm Explanation:
The key idea here is to use two passes to compute the product of elements except the current one, avoiding the division operation.
- First Pass (Left Products):
- Traverse the array from left to right. For each element
nums[i]
, compute the product of all the elements to its left and store it inoutput[i]
.
- Traverse the array from left to right. For each element
- Second Pass (Right Products):
- Traverse the array from right to left. For each element
nums[i]
, multiply the current value inoutput[i]
by the product of all the elements to its right. This way, we updateoutput[i]
to store the product of all elements exceptnums[i]
.
- Traverse the array from right to left. For each element
Code Implementation:
#include <stdio.h>
#include <stdlib.h>
void productExceptSelf(int* inputArray, int arraySize, int* outputArray)
{
int walkLeft = 1, walkRight = 1;
// First pass: calculate the left products
for (int i = 0; i < arraySize; i++) {
outputArray[i] = walkLeft;
walkLeft *= inputArray[i];
}
// Second pass: calculate the right products and update the output array
for (int i = arraySize - 1; i >= 0; i--) {
outputArray[i] *= walkRight;
walkRight *= inputArray[i];
}
}
int main()
{
int inputArray[] = {1, 2, 3, 4};
int arraySize = sizeof(inputArray) / sizeof(inputArray[0]);
int outputArray[arraySize];
productExceptSelf(inputArray, arraySize, outputArray);
for (int i = 0; i < arraySize; i++) {
printf("%d ", outputArray[i]);
}
return 0;
}
Explanation of the Code:
-
Initialization:
walkLeft
andwalkRight
are initialized to 1, used to accumulate the products as we traverse the array from left to right and right to left.
-
First Pass:
- We fill
outputArray
with the products of all elements to the left of each index. outputArray[i] = walkLeft
stores the left product of the elements.walkLeft *= inputArray[i]
updates the product for the next iteration.
- We fill
-
Second Pass:
- We multiply the current value of
outputArray[i]
bywalkRight
, which accumulates the products of elements to the right of the index. walkRight *= inputArray[i]
updates the product for the next iteration.
- We multiply the current value of
Time and Space Complexity:
- Time Complexity: O(n)O(n) where nn is the number of elements in the input array. We make two passes over the array.
- Space Complexity: O(1)O(1) extra space, because the output array is the only extra space used, and we’re not using additional space besides it.