Skip to content

Commit 67de492

Browse files
authored
Merge pull request #53 from NemoRaphtalia/Problem496
Solution #496 - Daniel - 16/06/2025
2 parents 107f0b7 + 595b98e commit 67de492

File tree

3 files changed

+179
-0
lines changed

3 files changed

+179
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# 496. Next Greater Element
2+
3+
**Difficulty:** *Easy*
4+
**Category:** *Arrays, Stack, Monotonic Stack*
5+
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/next-greater-element-i/description/)
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
*Given two arrays nums1 and nums2 where nums1 is a subset of nums2, the task is to find the next greater element for each element of nums1 in nums2. <br>
12+
The next greater element for an element x in nums2 is the first element to the right of x in nums2 that is greater than x. If it doesn’t exist, return -1 for that element.*
13+
14+
---
15+
16+
## 💡 Approach & Key Insights
17+
18+
*A brute-force approach would involve searching for each nums1[i] in nums2, and then scanning the rest of nums2 to find the next greater number.
19+
However, this can be optimized using a monotonic stack and a hash map to preprocess the nums2 list and determine the next greater element for each number in one pass.*
20+
21+
*<b>Key observations:</b><br>
22+
We can scan nums2 from left to right.<br>
23+
Use a stack to keep track of decreasing elements.<br>
24+
Whenever we find a greater number, we pop from the stack and set the mapping for the popped element.*
25+
26+
---
27+
28+
## 🛠️ Breakdown of Approaches
29+
30+
### 1️⃣ Brute Force / Naive Approach
31+
32+
- **Explanation:** *For each element in nums1, find its position in nums2, then iterate to the right of that position to find the first greater number. If none found, return -1.*
33+
- **Time Complexity:** *O(n * m) - Where n is the length of nums1 and m is the length of nums2.*
34+
- **Space Complexity:** *O(1) - No extra space beyond output list.*
35+
- **Example/Dry Run:**
36+
37+
```plaintext
38+
nums1 = [4, 1, 2]
39+
nums2 = [1, 3, 4, 2]
40+
41+
For 4 → search in nums2 → found at index 2 → no greater number → -1
42+
For 1 → search in nums2 → found at index 0 → 3 is greater → 3
43+
For 2 → found at index 3 → no greater number → -1
44+
Output: [-1, 3, -1]
45+
```
46+
47+
48+
### 2️⃣ Optimized Approach
49+
50+
- **Explanation:** *Use a monotonic stack to process nums2. While traversing, keep popping from the stack until the current number is greater than the stack top. Map each popped element to the current number. At the end, use the map to lookup results for nums1.*
51+
- **Time Complexity:** *O(n + m) - We process each element of nums2 only once.*
52+
- **Space Complexity:** *O(m) - For the hashmap and stack used to store next greater mappings.*
53+
- **Example/Dry Run:**
54+
55+
```plaintext
56+
nums1 = [4, 1, 2]
57+
nums2 = [1, 3, 4, 2]
58+
59+
Stack = []
60+
next_greater = {}
61+
62+
Process 1 → stack: [1]
63+
Process 3 → 3 > 1 → pop 1 → map[1] = 3 → stack: [3]
64+
Process 4 → 4 > 3 → pop 3 → map[3] = 4 → stack: [4]
65+
Process 2 → 2 < 4 → stack: [4, 2]
66+
67+
Remaining in stack: 4, 2 → no next greater → map[4] = -1, map[2] = -1
68+
69+
Now build result for nums1 using map:
70+
4 → -1
71+
1 → 3
72+
2 → -1
73+
74+
Output: [-1, 3, -1]
75+
```
76+
77+
---
78+
79+
## 📊 Complexity Analysis
80+
81+
| Approach | Time Complexity | Space Complexity |
82+
| ------------- | --------------- | ---------------- |
83+
| Brute Force | O(n * m) | O(1) |
84+
| Optimized | O(n + m) | O(m) |
85+
86+
---
87+
88+
## 📉 Optimization Ideas
89+
90+
*If multiple queries need to be answered for different nums1 but the same nums2, we can reuse the precomputed next_greater mapping.<br>
91+
This solution generalizes to "Next Greater Element II" with a circular array if needed.*
92+
93+
---
94+
95+
## 📌 Example Walkthroughs & Dry Runs
96+
97+
98+
```plaintext
99+
Input:
100+
nums1 = [2, 4]
101+
nums2 = [1, 2, 3, 4]
102+
103+
Stack trace:
104+
1 → push
105+
2 → push
106+
3 > 2 → pop 2 → map[2] = 3
107+
3 > 1 → pop 1 → map[1] = 3
108+
→ push 3
109+
4 > 3 → pop 3 → map[3] = 4
110+
→ push 4
111+
112+
Remaining in stack → 4 → map[4] = -1
113+
114+
Final map: {2: 3, 1: 3, 3: 4, 4: -1}
115+
Result for nums1 = [2, 4] → [3, -1]
116+
```
117+
118+
---
119+
120+
## 🔗 Additional Resources
121+
122+
- [Resource 1](https://www.youtube.com/watch?v=68a1Dc_qVq4)
123+
- [Resource 2](https://www.geeksforgeeks.org/dsa/stack-data-structure/)
124+
125+
---
126+
127+
Author: Daniel Nallapalli <br>
128+
Date: 16/06/2025
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Note: The returned array must be malloced, assume caller calls free().
3+
*/
4+
#define MAX_NUM 10001
5+
6+
int* nextGreaterElement(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {
7+
int* result = (int*)malloc(sizeof(int) * nums1Size);
8+
int next_greater[MAX_NUM];
9+
int stack[MAX_NUM];
10+
int top = -1;
11+
12+
for (int i = 0; i < MAX_NUM; i++) {
13+
next_greater[i] = -1;
14+
}
15+
16+
for (int i = 0; i < nums2Size; i++) {
17+
int current = nums2[i];
18+
while (top >= 0 && current > stack[top]) {
19+
int prev = stack[top--];
20+
next_greater[prev] = current;
21+
}
22+
stack[++top] = current;
23+
}
24+
25+
for (int i = 0; i < nums1Size; i++) {
26+
result[i] = next_greater[nums1[i]];
27+
}
28+
29+
*returnSize = nums1Size;
30+
return result;
31+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution(object):
2+
def nextGreaterElement(self, nums1, nums2):
3+
"""
4+
:type nums1: List[int]
5+
:type nums2: List[int]
6+
:rtype: List[int]
7+
"""
8+
next_greater = {}
9+
stack = []
10+
11+
for num in nums2:
12+
while stack and num > stack[-1]:
13+
prev = stack.pop()
14+
next_greater[prev] = num
15+
stack.append(num)
16+
17+
for num in stack:
18+
next_greater[num] = -1
19+
20+
return [next_greater[num] for num in nums1]

0 commit comments

Comments
 (0)