Command Palette

Search for a command to run...

Problem 9.6 · Stack and Monotonic StackEasy

Next Greater Element

What it teaches: Compute next-greater answers for one array with a monotonic stack, then look them up for another with a hash map.

Practise it on judges as “Next Greater Element I”.

The problem

nums1 is a subset of nums2 (all values distinct). For each x in nums1, find the first element to the right of x in nums2 that is greater than x, or −1.

Example 1

Input: nums1 = [4, 1, 2], nums2 = [1, 3, 4, 2]
Output: [-1, 3, -1]

Example 2

Input: nums1 = [2, 4], nums2 = [1, 2, 3, 4]
Output: [3, -1]

Constraints

  • 1 ≤ nums1.length ≤ nums2.length ≤ 1000
  • All values distinct

Pattern clues in the wording

  • → "Next greater" in an array
  • → Answers needed for selected values → hash map

These clues point to Monotonic Stack: Keep a stack whose values only increase (or decrease); each element pops everything it beats, finding "next greater/smaller" in one pass.

Stuck? Take one hint at a time

Solution.java · starter
import java.util.*;

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        return new int[nums1.length];
    }
}

Write your solution locally or in your editor for now. The in-browser runner (Java first, then Python, C++ and more) will run these tests right here.

Test cases

#InputExpected
1
nums1 = [4,1,2]
nums2 = [1,3,4,2]
[-1,3,-1]
2
nums1 = [2,4]
nums2 = [1,2,3,4]
[3,-1]

+ 1 hidden test the code runner will check

From slow to fast

Approaches

1

Optimal: monotonic stack + map

Time O(n + m) Space O(n)

Run the next-greater stack over nums2, recording next[value] = greater value when popping. Then answer each nums1 value from the map (default −1).

Approach 1
import java.util.*;

class Solution {
    public int[] nextGreaterElement(int[] nums1, int[] nums2) {
        Map<Integer, Integer> next = new HashMap<>();
        Deque<Integer> stack = new ArrayDeque<>();
        for (int x : nums2) {
            while (!stack.isEmpty() && x > stack.peek()) next.put(stack.pop(), x);
            stack.push(x);
        }
        int[] ans = new int[nums1.length];
        for (int i = 0; i < nums1.length; i++) ans[i] = next.getOrDefault(nums1[i], -1);
        return ans;
    }
}

Verdict: Linear.

Before you submit

Edge cases and common mistakes

Test these inputs

  • Largest value (−1)
  • Last element of nums2 (−1)

Mistakes people make

  • Searching nums2 from scratch for each query: O(n · m).

Interview

Follow-up questions

What if the array is circular (search wraps around)?