Skip to content

Commit 8c1fbdd

Browse files
authored
Merge pull request #1266 from PradnyaGaitonde/PradnyaGaitonde-patch-7
Create 0238-product-of-array-except-self.md
2 parents 06371d5 + 31a4dfc commit 8c1fbdd

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
---
2+
id: product-of-array-except-self
3+
title: Product of Array Except Self(LeetCode)
4+
sidebar_label: 0238-Product of Array Except Self
5+
tags:
6+
- Array
7+
- Prefix Sum
8+
description: 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].
9+
---
10+
11+
## Problem Statement
12+
13+
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]`.
14+
15+
The product of any prefix or suffix of `nums` is guaranteed to fit in a 32-bit integer.
16+
17+
You must write an algorithm that runs in `O(n)` time and without using the division operation.
18+
19+
### Examples
20+
21+
**Example 1:**
22+
23+
```plaintext
24+
Input: nums = [1,2,3,4]
25+
Output: [24,12,8,6]
26+
```
27+
28+
**Example 2:**
29+
30+
```plaintext
31+
Input: nums = [-1,1,0,-3,3]
32+
Output: [0,0,9,0,0]
33+
```
34+
35+
### Constraints
36+
37+
- `2 <= nums.length <= 105`
38+
- `30 <= nums[i] <= 30`
39+
- The product of any prefix or suffix of `nums` is guaranteed to fit in a 32-bit integer.
40+
41+
## Solution
42+
43+
We can solve this problem using multiple approaches. Here, I have explained all the possible solutions:
44+
45+
1. Brute Force Approach: Using nested loops to calculate the product of elements except for the current index.
46+
2. Dynamic Programming (Tabulation): Using two arrays to store the left and right products.
47+
3. Dynamic Programming (Space Optimization): Optimizing space usage by combining the two product arrays into a single array.
48+
49+
### Approach Brute Force (Two Nested Loops)
50+
51+
### Algorithm
52+
1. Initialize an empty vector `output`.
53+
2. Iterate through each element `i` in the array `nums`:
54+
* Set `product` to 1.
55+
* Iterate through each element `j` in the array `nums`:
56+
* If `i` equals `j`, skip this iteration.
57+
* Multiply `product` by `nums[j]`.
58+
* Append `product` to the `output` vector.
59+
3. Return the `output` vector.
60+
61+
#### Implementation
62+
63+
```C++
64+
class Solution {
65+
public:
66+
vector<int> productExceptSelf(vector<int>& nums) {
67+
int n = nums.size();
68+
vector<int> output;
69+
for(int i = 0; i < n; i++) {
70+
int product = 1;
71+
for(int j = 0; j < n; j++) {
72+
if(i == j) continue;
73+
product *= nums[j];
74+
}
75+
output.push_back(product);
76+
}
77+
return output;
78+
}
79+
};
80+
```
81+
82+
### Complexity Analysis
83+
84+
- **Time complexity**: O(N^2) - Two nested loops create a quadratic time complexity.
85+
- **Space complexity**: O(1) - No extra space except for the output array (which doesn't count towards space complexity).
86+
87+
### Approach 2: Dynamic Programming (Tabulation)
88+
89+
#### Algorithm
90+
91+
1. Initialize vectors `left_Product` and `right_Product` of size `n` with all elements set to 1.
92+
2. Calculate `left_Product`:
93+
* Set `left_Product[0]` to 1.
94+
* For each element `i` from 1 to `n-1`, set `left_Product[i]` to `left_Product[i-1]` multiplied by `nums[i-1]`.
95+
3. Calculate `right_Product`:
96+
* Set `right_Product[n-1]` to 1.
97+
* For each element `i` from `n-2` to 0, set `right_Product[i]` to `right_Product[i+1]` multiplied by `nums[i+1]`.
98+
4. Initialize vector `ans` of size `n`.
99+
5. For each element `i` from 0 to `n-1`, set `ans[i]` to `left_Product[i]` multiplied by `right_Product[i]`.
100+
6. Return the `ans` vector.
101+
102+
#### Implementation
103+
104+
```C++
105+
class Solution {
106+
public:
107+
vector<int> productExceptSelf(vector<int>& nums) {
108+
int n = nums.size();
109+
vector<int> ans(n);
110+
vector<int> left_Product(n);
111+
vector<int> right_Product(n);
112+
113+
left_Product[0] = 1;
114+
for(int i = 1; i < n; i++) {
115+
left_Product[i] = left_Product[i-1] * nums[i-1];
116+
}
117+
118+
right_Product[n-1] = 1;
119+
for(int i = n-2; i >= 0; i--) {
120+
right_Product[i] = right_Product[i+1] * nums[i+1];
121+
}
122+
123+
for(int i = 0; i < n; i++) {
124+
ans[i] = left_Product[i] * right_Product[i];
125+
}
126+
return ans;
127+
}
128+
};
129+
```
130+
131+
### Complexity Analysis
132+
133+
- **Time complexity**: O(N) - We iterate through the array three times.
134+
- **Space complexity**: O(N) - Two additional arrays (left_Product and right_Product) are used.
135+
136+
### Approach 3: Dynamic Programming (Space Optimization)
137+
138+
#### Algorithm
139+
140+
1. Initialize a vector `output` of size `n` with all elements set to 1.
141+
2. Calculate the left product:
142+
* Set `output[0]` to 1.
143+
* For each element `i` from 1 to `n-1`, set `output[i]` to `output[i-1]` multiplied by `nums[i-1]`.
144+
3. Calculate the right product:
145+
* Initialize `right` to 1.
146+
* For each element `i` from `n-1` to 0, set `output[i]` to `output[i]` multiplied by right, then set `right` to `right` multiplied by `nums[i]`.
147+
4. Return the `output` vector.
148+
149+
#### Implementation
150+
151+
```C++
152+
class Solution {
153+
public:
154+
vector<int> productExceptSelf(vector<int>& nums) {
155+
int n = nums.size();
156+
vector<int> output(n);
157+
158+
output[0] = 1;
159+
for(int i = 1; i < n; i++) {
160+
output[i] = output[i-1] * nums[i-1];
161+
}
162+
163+
int right = 1;
164+
for(int i = n-1; i >= 0; i--) {
165+
output[i] *= right;
166+
right *= nums[i];
167+
}
168+
return output;
169+
}
170+
};
171+
```
172+
173+
### Complexity Analysis
174+
175+
- **Time complexity**: O(N) - We iterate through the array twice.
176+
- **Space complexity**: O(1) - Constant space is used, except for the output array.
177+
178+
### Conclusion
179+
180+
By exploring various approaches to solve this problem, we can see that the brute force method, while simple, is inefficient with a time complexity of O(N^2). The dynamic programming approach with tabulation optimizes the time complexity to O(N) but uses extra space. The most optimized approach uses space-efficient dynamic programming, maintaining O(N) time complexity while reducing space complexity to O(1). This final approach is the best in terms of both time and space efficiency.

0 commit comments

Comments
 (0)