Next Greater Element Using Stack in DSA Go - Time & Space Complexity
We want to understand how the time taken grows when finding the next greater element for each item in a list using a stack.
How does the number of steps change as the list gets longer?
Analyze the time complexity of the following code snippet.
func nextGreaterElement(nums []int) []int {
result := make([]int, len(nums))
stack := []int{}
for i := len(nums) - 1; i >= 0; i-- {
for len(stack) > 0 && stack[len(stack)-1] <= nums[i] {
stack = stack[:len(stack)-1]
}
if len(stack) == 0 {
result[i] = -1
} else {
result[i] = stack[len(stack)-1]
}
stack = append(stack, nums[i])
}
return result
}
This code finds the next greater element for each number in the list by scanning from right to left using a stack.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: A single loop runs through the list once from right to left.
- Inner operation: The inner loop pops elements from the stack while they are smaller or equal to the current number.
- How many times: Each element is pushed and popped at most once, so the total inner loop operations across all iterations are limited.
As the list size grows, each element is processed once and pushed or popped from the stack at most once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 (push + pop per element) |
| 100 | About 200 |
| 1000 | About 2000 |
Pattern observation: The total operations grow roughly in a straight line with the input size.
Time Complexity: O(n)
This means the time taken grows directly in proportion to the number of elements in the list.
[X] Wrong: "The inner loop makes this algorithm O(n²) because it can run many times inside the outer loop."
[OK] Correct: Each element is pushed and popped only once, so the total inner loop operations across all iterations add up to n, not n squared.
Understanding this pattern helps you solve many problems involving next greater or smaller elements efficiently, a common skill interviewers look for.
"What if we changed the input to a circular list where the search wraps around? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem goal
The Next Greater Element problem asks to find for each element the first element to its right that is greater than it.Step 2: Recognize the stack usage
A stack helps track elements for which we haven't found a greater element yet, efficiently finding the next greater element to the right.Final Answer:
The first greater element to the right of each element -> Option AQuick Check:
NGE = first greater element on right [OK]
- Confusing next greater with next smaller element
- Looking to the left instead of right
- Thinking it sums elements instead of finding one
Solution
Step 1: Identify stack data structure in Go
Stacks can be implemented using slices in Go. An empty stack is an empty slice of ints: []int{}.Step 2: Check other options
stack := make(map[int]int) is a map, not a stack. stack := new(int) is a pointer to int, not a stack. stack := 0 is an int variable, not a stack.Final Answer:
stack := []int{} -> Option DQuick Check:
Stack as slice = []int{} [OK]
- Using map instead of slice for stack
- Using pointer instead of slice
- Initializing stack as int variable
[4, 5, 2, 25]?Solution
Step 1: Trace the array elements with stack
For 4, next greater is 5; for 5, next greater is 25; for 2, next greater is 25; for 25, no greater element, so -1.Step 2: Form the output array
Output is [5, 25, 25, -1].Final Answer:
[5, 25, 25, -1] -> Option AQuick Check:
Next greater elements found correctly [OK]
- Assigning -1 too early
- Mixing up indices in output
- Ignoring last element's -1
func nextGreater(arr []int) []int {
stack := []int{}
result := make([]int, len(arr))
for i := len(arr) - 1; i >= 0; i-- {
for len(stack) > 0 && stack[len(stack)-1] <= arr[i] {
stack = stack[:len(stack)-1]
}
if len(stack) == 0 {
result[i] = 0
} else {
result[i] = stack[len(stack)-1]
}
stack = append(stack, arr[i])
}
return result
}Solution
Step 1: Identify the no greater element marker
The code assigns 0 when no greater element is found, but the standard is to use -1.Step 2: Check other parts
Stack initialization and loop direction are correct. Comparison operator <= is correct for popping smaller or equal elements.Final Answer:
Result uses 0 instead of -1 for no greater element -> Option CQuick Check:
No greater element should be -1 [OK]
- Returning 0 instead of -1 for no greater element
- Changing loop direction incorrectly
- Wrong comparison operator causing wrong pops
[13, 7, 6, 12]. Using the Next Greater Element stack approach, what is the output array?Solution
Step 1: Find next greater for each element
For 13, no greater element to right, so -1. For 7, next greater is 12. For 6, next greater is 12. For 12, no greater element, so -1.Step 2: Write output array
Output is [-1, 12, 12, -1].Final Answer:
[-1, 12, 12, -1] -> Option BQuick Check:
Check right side for bigger numbers [OK]
- Assigning wrong next greater for 7 and 6
- Confusing output with input order
- Using 0 instead of -1 for no greater element
Ready to prove it?
Pass the test and this pattern moves unknown
