LeetCode 496 Next Greater Element I - From Brute Force to Optimized - Solution Explanation (Easy, Java, O(n))


The LeetCode problem "496. Next Greater Element I" asks us to find the first greater element to the right of each element in nums1
within nums2
, where nums1
is a subset of nums2
. If no such element exists, return -1. Below, we discuss two solutions: a brute force approach and an optimized solution using a monotonic stack, both implemented in Java.
Brute Force Solution
Approach
The brute force solution iterates through each element in nums1
. For each element, it:
- Searches for that element in
nums2
. - Once found, scans the elements to the right in
nums2
to find the first element greater than the current element. - If a greater element is found, stores it in the result array; otherwise, stores -1.
Complexity Analysis
- Time Complexity: O(n1 * n2), where
n1
is the length ofnums1
andn2
is the length ofnums2
. For each element innums1
, we potentially scan most ofnums2
to find the element and then scan the remaining elements to find the next greater one. - Space Complexity: O(1), excluding the output array, as we only use a few variables.
Code
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int[] ans = new int[len1];
for (int i = 0; i < len1; i++) {
// Initialize ans[i] to -1
ans[i] = -1;
// Find nums1[i] in nums2
for (int j = 0; j < len2; j++) {
if (nums2[j] == nums1[i]) {
// Look for the first next greater element
for (int k = j + 1; k < len2; k++) {
if (nums2[k] > nums1[i]) {
ans[i] = nums2[k];
break; // Stop after finding the first greater element
}
}
break; // No need to continue searching nums2 after finding nums1[i]
}
}
}
return ans;
}
}
Optimized Solution (Monotonic Stack)
Approach
The optimized solution uses a monotonic stack to efficiently find the next greater element for each element in nums2
, then maps these results to nums1
. The steps are:
- Initialize an empty stack and a hash map to store the next greater element for each number in
nums2
. - Iterate through
nums2
. For each element:- While the stack is not empty and the current element is greater than the stack's top element, pop the stack and map the popped element to the current element (as it is the next greater).
- Push the current element onto the stack.
- After processing
nums2
, any elements remaining in the stack have no next greater element, so map them to -1. - Create the result array by looking up each
nums1
element in the hash map.
This approach ensures we process each element in nums2
once and use the stack to maintain a decreasing order of elements, making it efficient.
Complexity Analysis
- Time Complexity: O(n1 + n2), where
n1
is the length ofnums1
andn2
is the length ofnums2
. Each element innums2
is pushed and popped at most once (O(n2)), and each element innums1
is looked up in the hash map (O(n1)). - Space Complexity: O(n2) for the stack and hash map, as they store up to
n2
elements.
Code
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
// Hash map to store next greater element for each number in nums2
Map<Integer, Integer> nextGreater = new HashMap<>();
// Stack to keep track of elements waiting for their next greater
Stack<Integer> stack = new Stack<>();
// Process nums2 to find next greater elements
for (int num : nums2) {
// While stack is not empty and current number is greater than stack top
while (!stack.isEmpty() && stack.peek() < num) {
// Pop element and map it to current number (next greater)
nextGreater.put(stack.pop(), num);
}
stack.push(num);
}
// Elements remaining in stack have no next greater element
while (!stack.isEmpty()) {
nextGreater.put(stack.pop(), -1);
}
// Create result array by mapping nums1 elements to their next greater
int[] ans = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
ans[i] = nextGreater.get(nums1[i]);
}
return ans;
}
}
Summary
- The brute force solution is straightforward but inefficient for large inputs due to its O(n1 n2) time complexity. It has been corrected to ensure it captures the first* greater element by adding a
break
statement. - The optimized solution uses a monotonic stack to achieve O(n1 + n2) time complexity, making it suitable for larger inputs. It leverages a stack to track elements waiting for their next greater element and a hash map for quick lookups, meeting the follow-up challenge's requirement.
Subscribe to my newsletter
Read articles from Anni Huang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Anni Huang
Anni Huang
I am Anni HUANG, a software engineer with 3 years of experience in IDE development and Chatbot.