Skip to content

Commit 102f574

Browse files
committed
Add Next Greater Element algorithm
1 parent 788d95b commit 102f574

File tree

1 file changed

+22
-128
lines changed

1 file changed

+22
-128
lines changed
Lines changed: 22 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,133 +1,27 @@
1-
from __future__ import annotations
2-
3-
arr = [-10, -5, 0, 5, 5.1, 11, 13, 21, 3, 4, -21, -10, -5, -1, 0]
4-
expect = [-5, 0, 5, 5.1, 11, 13, 21, -1, 4, -1, -10, -5, -1, 0, -1]
5-
6-
7-
def next_greatest_element_slow(arr: list[float]) -> list[float]:
8-
"""
9-
Get the Next Greatest Element (NGE) for each element in the array
10-
by checking all subsequent elements to find the next greater one.
11-
12-
This is a brute-force implementation, and it has a time complexity
13-
of O(n^2), where n is the size of the array.
14-
15-
Args:
16-
arr: List of numbers for which the NGE is calculated.
17-
18-
Returns:
19-
List containing the next greatest elements. If no
20-
greater element is found, -1 is placed in the result.
21-
22-
Example:
23-
>>> next_greatest_element_slow(arr) == expect
24-
True
25-
"""
26-
27-
result = []
28-
arr_size = len(arr)
29-
30-
for i in range(arr_size):
31-
next_element: float = -1
32-
for j in range(i + 1, arr_size):
33-
if arr[i] < arr[j]:
34-
next_element = arr[j]
35-
break
36-
result.append(next_element)
37-
return result
38-
39-
40-
def next_greatest_element_fast(arr: list[float]) -> list[float]:
41-
"""
42-
Find the Next Greatest Element (NGE) for each element in the array
43-
using a more readable approach. This implementation utilizes
44-
enumerate() for the outer loop and slicing for the inner loop.
45-
46-
While this improves readability over next_greatest_element_slow(),
47-
it still has a time complexity of O(n^2).
48-
49-
Args:
50-
arr: List of numbers for which the NGE is calculated.
51-
52-
Returns:
53-
List containing the next greatest elements. If no
54-
greater element is found, -1 is placed in the result.
55-
56-
Example:
57-
>>> next_greatest_element_fast(arr) == expect
58-
True
59-
"""
60-
result = []
61-
for i, outer in enumerate(arr):
62-
next_item: float = -1
63-
for inner in arr[i + 1 :]:
64-
if outer < inner:
65-
next_item = inner
66-
break
67-
result.append(next_item)
68-
return result
69-
70-
71-
def next_greatest_element(arr: list[float]) -> list[float]:
72-
"""
73-
Efficient solution to find the Next Greatest Element (NGE) for all elements
74-
using a stack. The time complexity is reduced to O(n), making it suitable
75-
for larger arrays.
76-
77-
The stack keeps track of elements for which the next greater element hasn't
78-
been found yet. By iterating through the array in reverse (from the last
79-
element to the first), the stack is used to efficiently determine the next
80-
greatest element for each element.
81-
82-
Args:
83-
arr: List of numbers for which the NGE is calculated.
84-
85-
Returns:
86-
List containing the next greatest elements. If no
87-
greater element is found, -1 is placed in the result.
88-
89-
Example:
90-
>>> next_greatest_element(arr) == expect
91-
True
92-
"""
93-
arr_size = len(arr)
94-
stack: list[float] = []
95-
result: list[float] = [-1] * arr_size
96-
97-
for index in reversed(range(arr_size)):
1+
"""
2+
Next Greater Element
3+
--------------------
4+
Given an array, find the next greater element for each element in the array.
5+
The next greater element for an element x is the first greater element on the
6+
right side of x in the array. If no such element exists, output -1.
7+
"""
8+
9+
def next_greater_elements(arr):
10+
stack = []
11+
result = [-1] * len(arr)
12+
13+
# Traverse from right to left
14+
for i in range(len(arr) - 1, -1, -1):
15+
while stack and stack[-1] <= arr[i]:
16+
stack.pop()
9817
if stack:
99-
while stack[-1] <= arr[index]:
100-
stack.pop()
101-
if not stack:
102-
break
103-
if stack:
104-
result[index] = stack[-1]
105-
stack.append(arr[index])
18+
result[i] = stack[-1]
19+
stack.append(arr[i])
10620
return result
10721

10822

10923
if __name__ == "__main__":
110-
from doctest import testmod
111-
from timeit import timeit
112-
113-
testmod()
114-
print(next_greatest_element_slow(arr))
115-
print(next_greatest_element_fast(arr))
116-
print(next_greatest_element(arr))
117-
118-
setup = (
119-
"from __main__ import arr, next_greatest_element_slow, "
120-
"next_greatest_element_fast, next_greatest_element"
121-
)
122-
print(
123-
"next_greatest_element_slow():",
124-
timeit("next_greatest_element_slow(arr)", setup=setup),
125-
)
126-
print(
127-
"next_greatest_element_fast():",
128-
timeit("next_greatest_element_fast(arr)", setup=setup),
129-
)
130-
print(
131-
" next_greatest_element():",
132-
timeit("next_greatest_element(arr)", setup=setup),
133-
)
24+
sample = [4, 5, 2, 25]
25+
print("Input:", sample)
26+
print("Next Greater Elements:", next_greater_elements(sample))
27+
# Output: [5, 25, 25, -1]

0 commit comments

Comments
 (0)