Next Greater Element I
Next Greater Element I
Hurry Up! Special Discount on our new DSA 3.0 Course is ending soon. Use code EARLY30
Stack
“We are given two arrays: nums1 (smaller) and nums2 (larger). For each element
in nums1, find where it appears in nums2. Once you find it in nums2, look to the right of
its position to find the next element that is larger. If no such element exists, return -1 for
that element. Collect these results in an array and return it.”
Examples
https://read.learnyard.com/dsa/next-greater-element-i/ 1/18
11/10/24, 7:01 PM Next Greater Element I
Constraints:
Intuition
The first thought that comes to mind is the simple simulation of the whole procedure for finding
the next greater element. This method is straightforward.
https://read.learnyard.com/dsa/next-greater-element-i/ 2/18
11/10/24, 7:01 PM Next Greater Element I
The problem requires finding the next greater element for each element in nums1 from the
array nums2. The "next greater element" for an element x in nums2 is the first element that is
greater than x and appears to the right of x in nums2. If no such element exists, the answer for
that element should be -1.
Approach:
1. Initialization:
2. Nested Loops:
Outer Loop: Iterate over each element in nums1. Let’s call the current element nums1[i].
First Inner Loop: For each nums1[i], iterate through nums2 to find the first occurrence
of nums1[i]. Let’s call the index of this occurrence j.
Second Inner Loop: Once nums1[i] is found in nums2 at index j, start another loop from
j + 1 to the end of nums2 to find the next greater element. If an element greater than
nums1[i] is found, store it in a temporary variable val and break the loop. If no such
element is found, val remains -1.
After processing all elements in nums1, return the ans vector which contains the next
greater elements or -1 if no such element exists.
https://read.learnyard.com/dsa/next-greater-element-i/ 3/18
11/10/24, 7:01 PM Next Greater Element I
Dry Run
Let’s perform a dry run of the provided code using the following example:
nums1 = [2, 4, 3]
nums2 = [1, 2, 3, 4, 5]
https://read.learnyard.com/dsa/next-greater-element-i/ 4/18
11/10/24, 7:01 PM Next Greater Element I
nums1 = [2, 4, 3]
nums2 = [1, 2, 3, 4, 5]
Result: [3]
Result: [3, 5]
Result: [3, 5, 4]
Final Result : The final result array ans for nums1 = [2, 4, 3] is [3, 5, 4].
class Solution {
public:
// Function to find the next greater element for each element in num
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums
// Update val
val = nums2[k];
https://read.learnyard.com/dsa/next-greater-element-i/ 6/18
11/10/24, 7:01 PM Next Greater Element I
The outermost loop iterates over each element in nums1, which contributes O(n1).
For each element in nums1, we need to find its position in nums2, leading to an O(n2)
operation.
Once the position is found, we then iterate through the remaining elements in nums2 to
find the next greater element, which in the worst case takes O(n2).
Thus, the total time complexity becomes O(n1×n2×n2). This can be inefficient for large inputs, as
the time taken grows quickly with the size of the input arrays.
“As we saw the time complexity of the brute force approach is O(n³) which is insufficient for
large inputs, so lets move towards building a more optimized approach. ”
Optimal Approach
https://read.learnyard.com/dsa/next-greater-element-i/ 7/18
11/10/24, 7:01 PM Next Greater Element I
Intuition
To improve the time complexity of finding the next greater element, we need to identify
patterns in the problem that can guide us towards a more efficient solution. Let’s analyze the
input array from left to right and consider the following observations:
Important Observations
When traversing the input array, we can encounter two main cases:
In a sequence where elements are in decreasing order, the first next greater value will be
the next greater element for all the values in the sequence.
For example, in the sequence [6, 4, 3], the next greater element for 6, 4, and 3 is 8, the first
value greater than all of them. Similarly, in the sequences [8, 7] and [2, 1], their next greater
elements would be 12 and 5 respectively.
https://read.learnyard.com/dsa/next-greater-element-i/ 8/18
11/10/24, 7:01 PM Next Greater Element I
In a sequence where elements are in increasing order, each element’s adjacent element is
the next greater element.
For example, in the sequence [12, 15, 16], the next greater element for 12 is 15, and for 15,
it is 16. Similarly, in the sequence [5, 11, 13], the next greater element for 5 is 11, and for 11,
it is 13.
To identify the next greater elements efficiently, we can traverse the array from left to right.
When we find the first element that is greater than the previous elements, we can stop and save
it as the next greater element for those elements. This greater element can also serve as the
next greater element for some preceding elements.
To better understand this procedure, we can say that elements need to wait until their next
greater element arrives. As we observed, there can be two types of sequences: either an
increasing order sequence or a decreasing order sequence. In an increasing order sequence,
only one element is waiting each time, and the current element becomes the next greater
element for that single waiting element. On the other hand, in a decreasing order sequence,
there can be many previous elements waiting for their next greater element. In this case, if the
current element breaks the decreasing order of the sequence, it becomes the next greater
element for all the waiting elements that are lesser than its value.
https://read.learnyard.com/dsa/next-greater-element-i/ 9/18
11/10/24, 7:01 PM Next Greater Element I
https://read.learnyard.com/dsa/next-greater-element-i/ 10/18
11/10/24, 7:01 PM Next Greater Element I
As the elements which we are storing are coming out in the LIFO fashion (Last in First Out), the
most used data structure which is used for such situations is nothing but a Stack.
Approach
We utilize a stack to identify the next greater elements for each element in the second
array.
As we iterate through the second array, we maintain elements in the stack in a way that
the top of the stack always holds the index of the current highest element for which we
are yet to find a next greater element.
For each element, we pop elements from the stack until we find a greater element or
the stack becomes empty. The popped elements have found their next greater element.
We store these results in a hash map where the key is the element and the value is its
next greater element.
For each element in the first array, we directly fetch the next greater element from the
hash map.
https://read.learnyard.com/dsa/next-greater-element-i/ 11/18
11/10/24, 7:01 PM Next Greater Element I
0:00 / 1:29 1×
Dry Run
let’s perform a dry run of the monotonic stack approach using the following example:
nums1 = [4, 1, 2]
nums2 = [1, 3, 4, 2]
Initialize:
Stack: []
NextGreaterMap: {}
Traverse nums2 from right to left:
Step 1:
Current Element: nums2[4] = 5
Stack: []
Since the stack is empty, there is no next greater element for 5.
NextGreaterMap: {5: -1}
Stack after pushing 5: [5]
Step 2:
Current Element: nums2[3] = 4
Stack: [5]
The top element of the stack (5) is greater than 4.
NextGreaterMap: {5: -1, 4: 5}
Stack after pushing 4: [5, 4]
https://read.learnyard.com/dsa/next-greater-element-i/ 12/18
11/10/24, 7:01 PM Next Greater Element I
Step 3:
Current Element: nums2[2] = 3
Stack: [5, 4]
The top element of the stack (4) is greater than 3.
NextGreaterMap: {5: -1, 4: 5, 3: 4}
Stack after pushing 3: [5, 4, 3]
Step 4:
Current Element: nums2[1] = 2
Stack: [5, 4, 3]
The top element of the stack (3) is greater than 2.
NextGreaterMap: {5: -1, 4: 5, 3: 4, 2: 3}
Stack after pushing 2: [5, 4, 3, 2]
Step 5:
Current Element: nums2[0] = 1
Stack: [5, 4, 3, 2]
The top element of the stack (2) is greater than 1.
NextGreaterMap: {5: -1, 4: 5, 3: 4, 2: 3, 1: 2}
Stack after pushing 1: [5, 4, 3, 2, 1]
Final NextGreaterMap: {1: 2, 2: 3, 3: 4, 4: 5, 5: -1}
To find the result for nums1 = [2, 4, 3], we use the NextGreaterMap:
For 2: NextGreaterMap[2] is 3
For 4: NextGreaterMap[4] is 5
For 3: NextGreaterMap[3] is 4
Result: [3, 5, 4]
class Solution {
public:
// Function to find the next greater element for each element in num
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums
stack.push(-1);
// Hash map to store the next greater element for each number in
unordered_map<int, int> nextGreaterMap;
https://read.learnyard.com/dsa/next-greater-element-i/ 14/18
11/10/24, 7:01 PM Next Greater Element I
Using a stack, each element in nums2 is pushed and popped at most once, which means all
stack operations take O(n) time where n is the length of nums2.
3. For each element in nums1, we use nextGreaterMap to find the next greater element in
constant time.
This lookup operation takes O(m) time in total, where m is the length of nums1.
Here, n is the length of nums2 for building the map, and m is the length of nums1 for
constructing the result array.
2. We use a stack to help efficiently find the next greater element for each element in nums2.
In the worst case, every element of nums2 could be pushed onto the stack (for example, if
nums2 is strictly decreasing).
So, the space needed for the stack can be up to O(n), where n is the length of nums2.
3. After determining the next greater element for each element in nums2, we store these
mappings in a hash map.
This hash map allows us to look up the next greater element for any element in nums1 in
constant time.
Since there are n elements in nums2, we need O(n) space for this hash map.
4. We create a result array to store the next greater element for each element in nums1.
This space is necessary to store the final output, so it requires O(m) space.
https://read.learnyard.com/dsa/next-greater-element-i/ 15/18
11/10/24, 7:01 PM Next Greater Element I
The total space complexity is the sum of the individual space requirements: O(n) (stack) +
O(n) (hash map) + O(m) (result array) = O(n + m)
Here, n represents the number of elements in nums2, and m represents the number of
elements in nums1.
So, the overall space complexity is O(n + m), where we need space proportional to the lengths
of both nums2 and nums1.
This particular approach is suitable for large input size of order of 10⁵
Key Takeaways
The technique of using a stack with a monotonic property (either increasing or decreasing) is
often referred to as a Monotonic stack. Many problems can be efficiently solved using this
approach, so it is important to become familiar with it.
The monotonic stack approach revolves around utilizing a stack data structure to solve specific
types of problems efficiently.
It is based on the idea of maintaining a monotonic property, either increasing or decreasing,
while processing the elements of an array or sequence.
When processing a new element, you pop elements from the stack until you find an
element smaller than the current element.
When processing a new element, you pop elements from the stack until you find an
element larger than the current element.
https://read.learnyard.com/dsa/next-greater-element-i/ 16/18
11/10/24, 7:01 PM Next Greater Element I
1. The monotonic stack allows certain types of problems to be solved in linear time, O(n). This
is because each element is pushed and popped from the stack at most once.
2. It simplifies the logic for problems involving finding the next/previous greater/smaller
elements. Instead of using nested loops which can be complex and inefficient, a single pass
with a stack suffices.
3. It can be applied to a variety of problems in different domains, such as arrays, histograms,
and even strings.
Learning Tip
Since we have solved the Next Greater Element problem, let’s now tackle the following related
problems:
Next - Stack
Coming Soon...
About Feedback
Copyright © 2024
https://read.learnyard.com/dsa/next-greater-element-i/ 18/18