The next greater element of some element x in an array is the first greater element that is to the right of x 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 0 <= i < nums1.length, find the index j such that nums1[i] == nums2[j] and determine the next greater element of nums2[j] 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.

Input: nums1 = [4,1,2], nums2 = [1,3,4,2]
Output: [-1,3,-1]
Explanation: The next greater element for each value of nums1 is as follows:
4 is highlighted in nums2 = [1, 3, 4, 2]. There is no next greater element, so the answer is -1.
1 is highlighted in nums2 = [1, 3, 4, 2]. The next greater element is 3.
2 is highlighted in nums2 = [1, 3, 4, 2]. There is no next greater element, so the answer is -1.
Input: nums1 = [2,4], nums2 = [1,2,3,4]
Output: [3,-1]
Explanation: The next greater element for each value of nums1 is as follows:
2 is highlighted in nums2 = [1, 2, 3, 4]. The next greater element is 3.
4 is highlighted in nums2 = [1, 2, 3, 4]. There is no next greater element, so the answer is -1.

Follow-up: Could you find an O(nums1.length + nums2.length) solution?

Contents

In this approach, we are going to loop through each number in nums1 array and then loop through nums2 array to find where the number is located and get next immediate greater element if exists.

public class NextGreaterElement1 { /* iteration over both arrays and for each number in nums1, find next immediate greater element if exists from nums2 */ static int[] usingIterateOverArrays(int[] nums1, int[] nums2) { for(int i=0;i <nums1.length; i++) { int num = nums1[i]; int nextGreater=0; for(int j=0; j<nums2.length; j++) { if(nums2[j] == num) { nextGreater = -1; } if(nextGreater == -1 && nums2[j] > num) { nextGreater = nums2[j]; break; } } nums1[i] = nextGreater; } return nums1; } }
Complexity Analysis:

Time complexity: Above code runs in O(n * m) time where n is the length of input array nums2 and m is the length of input array nums1. This is because for every number in nums1 we are looping through nums2.
Space complexity: O(m) for the answer array, in the above implementation, we are modifying input array nums1 itself, but you can create a new array for the result.

Main intution of this approach is that, we are going to loop through nums2 elements and for each number, find the next immediate greater element and store this mapping in a HashMap, then it is easy to find greater elements for the numbers in nums1 array.

Implementation details

If we have to capture next greater element for every number in nums2, one possible way is to scan throguh nums2 array again for each number, but this is going to be O(n2) time complexity.

Since we are looking for next immediate greater element, there is a better way to capture that using a Stack.

Let's understand with an example, say nums1 = [4, 1, 2] and nums2 = [1, 3, 4, 2].

import java.util.HashMap; import java.util.Stack; public class NextGreaterElement1 { /* For every number in nums2, store next greater element possible in a Map, then loop through nums1 and get greater element from already computed Map */ static int[] usingStackAndMap(int[] nums1, int[] nums2) { Stack<Integer> stack = new Stack<>(); HashMap<Integer, Integer> map = new HashMap<>(); for(int i=0; i<nums2.length; i++) { int currentNum = nums2[i]; while(!stack.isEmpty() && currentNum > stack.peek()) { map.put(stack.pop(), currentNum); } stack.push(currentNum); } // If stack still have elements left while(!stack.isEmpty()) { map.put(stack.pop(), -1); } // now, iterate through nums1 array an find the next greatest element from map which we stored above for(int i=0; i<nums1.length; i++) { nums1[i] = map.get(nums1[i]); } return nums1; } }
Complexity Analysis:

Time complexity: Above code runs in O(n + m) time where n is the length of input array nums2 and m is the length of input array nums1. This is because we are looping through nums2 array once and nums1 array once, we can say that the time complexity is O(n) because nums1 array is a subset of nums2, so atmost we will be iterating over O(2n) time, that implies to O(n).
Space complexity: O(n) for the HashMap and Stack that we are using.

Above implementations source code can be found at GitHub link for Java code