Skip to content

Commit bcc8083

Browse files
committed
Solution for next greater element 2
1 parent 5dd7da3 commit bcc8083

File tree

4 files changed

+180
-0
lines changed

4 files changed

+180
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# 503. Next Greater Element II
2+
3+
**Difficulty:** Medium
4+
**Category:** Arrays, Stack, Monotonic Stack
5+
**Leetcode Link:** [Problem Link](https://leetcode.com/problems/next-greater-element-ii)
6+
7+
---
8+
9+
## 📝 Introduction
10+
11+
Given a circular array, the task is to find the next greater element for each element in the array. The "next greater element" for a number x is the first greater number traversing the array in the forward direction. If it doesn’t exist, assign -1. Since the array is circular, we simulate traversing the array twice.
12+
13+
Constraints typically include:<br>
14+
- 1 ≤ nums.length ≤ 10⁴
15+
- -10⁹ ≤ nums[i] ≤ 10⁹
16+
17+
---
18+
19+
## 💡 Approach & Key Insights
20+
21+
The brute force solution involves checking for the next greater element by looping through the array for each element. This leads to O(n²) time complexity.
22+
23+
The optimized approach uses a monotonic decreasing stack and processes the array twice to simulate circularity. While traversing in reverse, we pop elements smaller than or equal to the current one from the stack. If the stack is not empty, the top is the next greater element.
24+
25+
---
26+
27+
## 🛠️ Breakdown of Approaches
28+
29+
### 1️⃣ Brute Force / Naive Approach
30+
31+
- **Explanation:**
32+
For each element, we look forward in the array (circularly) to find the next greater number. This requires a nested loop.
33+
- **Time Complexity:** O(n²) – We iterate through the array for each element.
34+
- **Space Complexity:** O(1) – No extra space except for the output.
35+
- **Example/Dry Run:**
36+
37+
```plaintext
38+
Input: [1, 2, 1]
39+
i = 0 → 2 is next greater → ans[0] = 2
40+
i = 1 → no element greater → ans[1] = -1
41+
i = 2 → 2 is next greater (wraps around) → ans[2] = 2
42+
Output: [2, -1, 2]
43+
```
44+
45+
### 2️⃣ Optimized Approach
46+
47+
- **Explanation:**
48+
We use a stack to maintain indices in a decreasing order of values. We traverse the array twice in reverse order to simulate the circular array. At each index, we pop all smaller or equal values. If the stack is not empty, the top of the stack is the next greater element.
49+
- **Time Complexity:** O(n) – Each element is pushed and popped at most once.
50+
- **Space Complexity:** O(n) – For the stack and output array.
51+
- **Example/Dry Run:**
52+
53+
```plaintext
54+
Input: [1, 2, 1]
55+
Initialize ans = [-1, -1, -1]
56+
Pass 1 (i = 5 to 0): (simulate 2*n = 6 steps)
57+
58+
i=5 → idx=2 → stack=[], ans[2]=-1 → push 1
59+
i=4 → idx=1 → stack=[1], 2>1 → pop → stack=[], ans[1]=-1 → push 2
60+
i=3 → idx=0 → stack=[2], 2>1 → ans[0]=2 → push 1
61+
i=2 → idx=2 → stack=[2,1], top=1==1 → pop → stack=[2], top=2>1 → ans[2]=2 → push 1
62+
i=1 → idx=1 → top=1<2 → ans[1]=-1 (already assigned) → push 2
63+
i=0 → idx=0 → ans[0]=2 (already assigned)
64+
65+
Final Output: [2, -1, 2]
66+
```
67+
68+
### 3️⃣ Best / Final Optimized Approach
69+
70+
- **Explanation:**
71+
Same as optimized above using a monotonic decreasing stack. The idea of traversing 2n times in reverse is optimal and handles circularity efficiently.
72+
- **Time Complexity:** O(n) – Each index is processed at most twice.
73+
- **Space Complexity:** O(n) – Stack and output array.
74+
75+
---
76+
77+
## 📊 Complexity Analysis
78+
79+
| Approach | Time Complexity | Space Complexity |
80+
| ------------- | --------------- | ---------------- |
81+
| Brute Force | O(n²) | O(1) |
82+
| Optimized | O(n) | O(n) |
83+
| Best Approach | O(n) | O(n) |
84+
85+
---
86+
87+
## 📉 Optimization Ideas
88+
89+
This problem is well-optimized with a monotonic stack. Further optimization is not needed. Any approach faster than O(n) is not feasible as every element must be checked at least once.
90+
91+
---
92+
93+
## 📌 Example Walkthroughs & Dry Runs
94+
95+
```plaintext
96+
Example:
97+
Input: [1, 2, 3, 4, 3]
98+
99+
i=4 → 3 → stack=[], ans[4]=-1 → push 3
100+
i=3 → 4 → pop 3, stack=[], ans[3]=-1 → push 4
101+
i=2 → 3 → 4>3 → ans[2]=4 → push 3
102+
i=1 → 2 → 3>2 → ans[1]=3 → push 2
103+
i=0 → 1 → 2>1 → ans[0]=2 → push 1
104+
105+
Output: [2, 3, 4, -1, 4]
106+
```
107+
108+
---
109+
110+
## 🔗 Additional Resources
111+
112+
- [Monotonic Stack - Intuition](https://www.geeksforgeeks.org/dsa/introduction-to-monotonic-stack-2/)
113+
- [Java Stack Docs](https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html)
114+
115+
---
116+
117+
Author: Abdul Wahab
118+
Date: 19/07/2025
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Solution {
2+
public:
3+
vector<int> nextGreaterElements(vector<int>& nums) {
4+
int n = nums.size();
5+
stack<int> st;
6+
vector<int> ans(n);
7+
// Initialize stack for circular behavior
8+
for (int i = n - 1; i >= 0; i--) {
9+
st.push(nums[i]);
10+
}
11+
for (int i = n - 1; i >= 0; i--) {
12+
while (!st.empty() && nums[i] >= st.top()) {
13+
st.pop();
14+
}
15+
if (st.empty())
16+
ans[i] = -1;
17+
else
18+
ans[i] = st.top();
19+
st.push(nums[i]);
20+
}
21+
return ans;
22+
}
23+
};
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public int[] nextGreaterElements(int[] nums) {
3+
int n = nums.length;
4+
Stack<Integer> st = new Stack<>();
5+
int ans[] = new int[n];
6+
// Initialize stack for circular behavior
7+
for (int i = n - 1; i >= 0; i--) {
8+
st.push(nums[i]);
9+
}
10+
for (int i = n - 1; i >= 0; i--) {
11+
while (!st.isEmpty() && nums[i] >= st.peek()) {
12+
st.pop();
13+
}
14+
if (st.isEmpty())
15+
ans[i] = -1;
16+
else
17+
ans[i] = st.peek();
18+
st.push(nums[i]);
19+
}
20+
return ans;
21+
}
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution:
2+
def nextGreaterElements(self, nums: List[int]) -> List[int]:
3+
n = len(nums)
4+
stack = []
5+
ans = [0] * n
6+
# Preload stack with reversed nums for circular behavior
7+
for i in range(n - 1, -1, -1):
8+
stack.append(nums[i])
9+
for i in range(n - 1, -1, -1):
10+
while stack and nums[i] >= stack[-1]:
11+
stack.pop()
12+
if not stack:
13+
ans[i] = -1
14+
else:
15+
ans[i] = stack[-1]
16+
stack.append(nums[i])
17+
return ans

0 commit comments

Comments
 (0)