📊Next Greater Element I
Question (LC.496)
Two integer arrays
nums1
andnums2
are given as input.nums2
is the main array.nums1
is a subset ofnums2
. Find all the next greater elements for each element innums1
Example
Input: nums1 = [4,1,2], nums2 = [1,3,4,2]
Output: [-1,3,-1]
Initial Approach
For each element in nums1
find it in nums2
and find the element greater than itself
O(n1 * n2)
Code
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
int[] results = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
results[i] = nextGreaterHelper(nums1[i], nums2);
}
return results;
}
private int nextGreaterHelper(int element, int[] nums) {
// if element is not in nums or does not have a greater element
// return -1
if (nums == null || nums.length == 0) {
return -1;
}
int eleIndex = -1;
for (int i = 0; i < nums.length; i++) {
if (element == nums[i]) {
eleIndex = i;
break;
}
}
if (eleIndex == -1) {
return -1;
}
for (int i = eleIndex + 1; i < nums.length; i++) {
if (nums[i] > element) {
return nums[i];
}
}
return -1;
}
Test cases are easy for this question. The run time is 2ms and beats 98% of the solutions.
Monotonic Stack Approach
A classic example
Push to a min stack
elements in stack do not have a greater element yet
Pop when the current element is bigger
all the elements in stack smaller than the current element has a next greater element now
Code
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
// look up index by value
Map<Integer, Integer> valToIndex = new HashMap<>();
for (int i = 0; i < nums2.length; i++) {
valToIndex.put(nums2[i], i);
}
// right bounds
int[] rightBounds = new int[nums2.length];
for (int i = 0; i < rightBounds.length; i++) {
rightBounds[i] = -1;
}
// store index in stack
Stack<Integer> minStack = new Stack<>();
for (int i = 0; i < nums2.length; i++) {
// pop
while (!minStack.isEmpty() && nums2[minStack.peek().intValue()] < nums2[i]) {
// nums2[i] is the next greater element to the element in stack
int popIndex = minStack.pop().intValue();
rightBounds[popIndex] = nums2[i];
}
minStack.push(i);
}
int[] results = new int[nums1.length];
for (int i = 0; i < nums1.length; i++) {
int lookupIndex = valToIndex.get(nums1[i]);
results[i] = rightBounds[lookupIndex];
}
return results;
}
Time O(n1 + n2)
Space O(n2)
Last updated