Description
The next greater element of some element in an array is the first greater element that is to the right of in the same array.
You are given two distinct 0-indexed integer arrays nums1 and nums2, where nums1 is a subset of nums2.
For each , find the index such that and determine the next greater element of in nums2. If there is no next greater element, then the answer for this query is -1.
Return an array ans of length nums1.length such that ans[i] is the next greater element as described above.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2]
Output: [-1,3,-1]
Explanation:
- For
4innums1:4is atnums2[2]. There is no element greater than4to its right. Answer is-1. - For
1innums1:1is atnums2[0]. The next element greater than1to its right is3. Answer is3. - For
2innums1:2is atnums2[3]. There is no element to its right. Answer is-1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4]
Output: [3,-1]
Constraints:
- All integers in
nums1andnums2are unique. - All the integers of
nums1also appear innums2.
Approach 1: Brute Force with Hash Map
Intuition
First, record the index of every element in nums2 using a hash map so we can jump straight to its position. For each number in nums1, start scanning to the right in nums2 starting from that index until we find the first element strictly larger than it.
import java.util.HashMap;
import java.util.Map;
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Map<Integer, Integer> indexMap = new HashMap<>();
for (int i = 0; i < nums2.length; i++) {
indexMap.put(nums2[i], i);
}
int[] result = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
int num = nums1[i];
int startIndex = indexMap.get(num);
int nextGreater = -1;
for (int j = startIndex + 1; j < nums2.length; j++) {
if (nums2[j] > num) {
nextGreater = nums2[j];
break;
}
}
result[i] = nextGreater;
}
return result;
}
}
Complexity
- Time Complexity: — Where and . In the worst case, we scan up to elements for each of the elements in
nums1. - Space Complexity: — Hash map stores indices of elements in
nums2.
Most Optimized Solution: Monotonic Stack + Hash Map ()
Intuition
Instead of searching to the right repeatedly, precompute the next greater element for every number in nums2 in a single pass using a Monotonic Decreasing Stack:
- Maintain a stack of elements that are still waiting to find their “next greater element.”
- Iterate through
nums2. For each current numbernum:- While
numis larger than the top element of the stack,numis the next greater element for that top value! Pop it from the stack and store(popped_value -> num)in a Hash Map.
- While
- Push
numonto the stack. - After processing
nums2, any numbers remaining in the stack have no greater element to their right, so their mapped value is-1(defaulting viagetOrDefault). - Finally, construct the answer array by doing map lookups for each element in
nums1.
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Map<Integer, Integer> nextGreaterMap = new HashMap<>();
Stack<Integer> stack = new Stack<>();
for (int num : nums2) {
// While current number is greater than stack's top, map top -> num
while (!stack.isEmpty() && stack.peek() < num) {
nextGreaterMap.put(stack.pop(), num);
}
stack.push(num);
}
// Build result for nums1 using precomputed map
int[] result = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
result[i] = nextGreaterMap.getOrDefault(nums1[i], -1);
}
return result;
}
}
Complexity
- Time Complexity: — Each element of
nums2is pushed and popped from the stack at most once (). Building the result array takes time. - Space Complexity: — Stack and Hash Map store up to elements from
nums2.
Easy Memory Rule
“Maintain a decreasing stack for
nums2. When a bigger number comes along, pop smaller numbers and save(popped_item -> bigger_number)in a map.”
Core Data Structures
Stack<Integer>: Stores numbers fromnums2whose next greater element has not been found yet. Because elements are kept in decreasing order, the smallest number in the stack is always at the top (stack.peek()).Map<Integer, Integer>: Stores the result for each processed number as a key-value pair:(Number -> Next Greater Element).
Phase 1: Finding Next Greater Elements in nums2
We iterate through nums2 element by element (num):
- Compare with Stack Top (
while (!stack.isEmpty() && stack.peek() < num)):- Before pushing
numonto the stack, check ifnumis strictly greater than the number at the top of the stack. - If
numis greater, thennumis the first element to the right that is larger thanstack.peek().
- Before pushing
- Pop and Record (
nextGreaterMap.put(stack.pop(), num)):- Remove the top element from the stack using
stack.pop(). - Save the relationship in the map: key = popped element, value =
num. - Continue this loop to check if
numis also greater than the next element below it in the stack.
- Remove the top element from the stack using
- Push Current Element (
stack.push(num)):- Push
numonto the stack so its own next greater element can be determined in future iterations.
- Push
Phase 2: Generating Output for nums1
We iterate through nums1 and retrieve the precomputed answers:
- For each
nums1[i], perform a lookup innextGreaterMap. nextGreaterMap.getOrDefault(nums1[i], -1):- If
nums1[i]was popped during Phase 1, return its mapped value. - If
nums1[i]remained in the stack at the end, no larger element existed to its right, so return-1.
- If
Exact Step-by-Step Code Trace
Given nums2 = [2, 1, 3] and nums1 = [1, 2]:
Iteration 1 (num = 2):
- Stack is empty. Skip
whileloop. - Execute
stack.push(2). - Stack:
[2]| Map:{}
Iteration 2 (num = 1):
stack.peek()is2. Since2 < 1is false, skipwhileloop.- Execute
stack.push(1). - Stack:
[2, 1]| Map:{}
Iteration 3 (num = 3):
-
stack.peek()is1. Since1 < 3is true: -
Pop
1. Storemap.put(1, 3). -
stack.peek()is2. Since2 < 3is true: -
Pop
2. Storemap.put(2, 3). -
Stack is now empty. Exit
whileloop. -
Execute
stack.push(3). -
Stack:
[3]| Map:{1: 3, 2: 3}
Lookup Phase (nums1 = [1, 2]):
- For
1:map.getOrDefault(1, -1)3 - For
2:map.getOrDefault(2, -1)3 - Output:
[3, 3]