Next Greater Element Using Stack in DSA Java - Time & Space Complexity
We want to understand how the time needed to find the next greater element for each item grows as the list gets bigger.
How does the number of steps change when the input size increases?
Analyze the time complexity of the following code snippet.
public int[] nextGreaterElement(int[] nums) {
int n = nums.length;
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && stack.peek() <= nums[i]) {
stack.pop();
}
result[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(nums[i]);
}
return result;
}
This code finds the next greater number to the right for each element in the array using a stack.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop going through the array from right to left.
- How many times: The loop runs once for each element (n times).
- Stack operations: Each element is pushed once and popped at most once.
As the input size grows, each element is processed a limited number of times due to stack push and pop.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 stack operations (push/pop) plus 10 loop steps |
| 100 | About 200 stack operations plus 100 loop steps |
| 1000 | About 2000 stack operations plus 1000 loop steps |
Pattern observation: The total operations grow roughly in a straight line with input size, not faster.
Time Complexity: O(n)
This means the time to find all next greater elements grows directly in proportion to the number of elements.
[X] Wrong: "Because there is a nested while loop inside the for loop, the time complexity must be O(n²)."
[OK] Correct: Each element is pushed and popped at most once, so the total work inside the while loop across all iterations is limited to n, not n².
Understanding this pattern shows you how to use stacks to solve problems efficiently, a skill that helps in many coding challenges and real tasks.
"What if we changed the input array to be circular (the end connects to the start)? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem definition
The Next Greater Element problem asks to find, for each element, the first element to its right that is greater than it.Step 2: Identify the role of the stack
The stack helps keep track of elements for which we haven't found a greater element yet, allowing efficient lookup.Final Answer:
The first greater element to the right of each element -> Option CQuick Check:
Next Greater Element = first greater right element [OK]
- Confusing next greater with next smaller element
- Searching to the left instead of right
- Thinking it finds max element overall
Solution
Step 1: Check Java generic syntax for Stack
Java uses generics with angle brackets and wrapper classes, so Stack<Integer> stack = new Stack<>(); is correct.Step 2: Identify errors in other options
Stack stack = new Stack<int>(); misses generic type parameter syntax; Stack<int> stack = new Stack<>(); uses primitive int which is invalid; Stack<> stack = new Stack<Integer>(); has incorrect generic syntax.Final Answer:
Stack<Integer> stack = new Stack<>(); -> Option BQuick Check:
Use wrapper class Integer with generics [OK]
- Using primitive int instead of Integer in generics
- Missing generic type parameter <>
- Incorrect generic syntax placement
int[] arr = {4, 5, 2, 25};
int[] nge = nextGreaterElement(arr);
System.out.println(Arrays.toString(nge));
public static int[] nextGreaterElement(int[] nums) {
int n = nums.length;
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
for (int i = n - 1; i >= 0; i--) {
while (!stack.isEmpty() && stack.peek() <= nums[i]) {
stack.pop();
}
result[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(nums[i]);
}
return result;
}Solution
Step 1: Trace from right to left
Start with i=3 (25): stack empty, result[3] = -1, push 25.
i=2 (2): stack top=25 > 2, result[2]=25, push 2.
i=1 (5): pop 2 (<=5), stack top=25 > 5, result[1]=25, push 5.
i=0 (4): stack top=5 > 4, result[0]=5, push 4.Step 2: Collect results
Result array is [5, 25, 25, -1].Final Answer:
[5, 25, 25, -1] -> Option AQuick Check:
Right side bigger elements found correctly [OK]
- Traversing left to right instead of right to left
- Not popping smaller or equal elements from stack
- Assigning wrong default -1 positions
public static int[] nextGreaterElement(int[] nums) {
int n = nums.length;
int[] result = new int[n];
Stack<Integer> stack = new Stack<>();
for (int i = 0; i < n; i++) {
while (!stack.isEmpty() && stack.peek() <= nums[i]) {
stack.pop();
}
result[i] = stack.isEmpty() ? -1 : stack.peek();
stack.push(nums[i]);
}
return result;
}Solution
Step 1: Analyze loop direction
The code loops from left to right, but Next Greater Element using stack requires right to left traversal to find next greater on the right.Step 2: Understand impact of loop direction
Looping left to right causes incorrect results because stack does not have future elements yet.Final Answer:
Loop should run from right to left (i = n-1 to 0) -> Option AQuick Check:
Traverse backward for correct next greater [OK]
- Looping forward instead of backward
- Using stack for values instead of indices (not always wrong but different approach)
- Not popping smaller or equal elements
{13, 7, 6, 12}, what is the Next Greater Element array using a stack? Also, explain why the last element's next greater element is -1.Solution
Step 1: Find next greater elements from right to left
Start with 12 (last element): no elements to right, so result is -1.
Next 6: next greater is 12.
Next 7: next greater is 12.
Next 13: no greater element to right, so -1.Step 2: Explain last element's result
The last element has no elements to its right, so no next greater element exists, hence -1.Final Answer:
[ -1, 12, 12, -1 ] -> Option DQuick Check:
Last element no right neighbor = -1 [OK]
- Assigning next greater for last element incorrectly
- Mixing up indices and values
- Not traversing array backward
Ready to prove it?
Pass the test and this pattern moves unknown
