LeetCode496-下一个更大元素I

题目链接

英文链接:https://leetcode.com/problems/next-greater-element-i/

中文链接:https://leetcode-cn.com/problems/next-greater-element-i/

题目详述

给定两个没有重复元素的数组 nums1 和 nums2 ,其中nums1 是 nums2 的子集。找到 nums1 中每个元素在 nums2 中的下一个比其大的值。

nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素。如果不存在,对应位置输出-1。

示例 1:

1
2
3
4
5
6
输入: nums1 = [4,1,2], nums2 = [1,3,4,2].
输出: [-1,3,-1]
解释:
对于num1中的数字4,你无法在第二个数组中找到下一个更大的数字,因此输出 -1。
对于num1中的数字1,第二个数组中数字1右边的下一个较大数字是 3。
对于num1中的数字2,第二个数组中没有下一个更大的数字,因此输出 -1。

示例 2:

1
2
3
4
5
输入: nums1 = [2,4], nums2 = [1,2,3,4].
输出: [3,-1]
解释:
对于num1中的数字2,第二个数组中的下一个较大数字是3。
对于num1中的数字4,第二个数组中没有下一个更大的数字,因此输出 -1。

注意:

  1. nums1和nums2中所有元素是唯一的。
  2. nums1和nums2 的数组大小都不超过1000。

题目详解

  • LeetCode739-每日温度 类似,都是找下一个比当前元素大的数。
  • 运用单调栈,保持元素从栈底到栈顶单调递减(可以相等,不严格单调)。
  • 遍历数组,如果当前元素比栈顶元素大,易知当前元素是第一个大于栈顶元素的元素,弹出栈顶元素进行结算,直到当前元素不大于栈顶元素或者栈为空。最后将当前元素压入栈。
  • 因为是两个数组,还需要一个 HashMap 来存储映射关系。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class LeetCode_00496 {

public int[] nextGreaterElement(int[] nums1, int[] nums2) {
Deque<Integer> stack = new ArrayDeque<>();
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums2) {
while (!stack.isEmpty() && num > stack.peek()) {
map.put(stack.pop(), num);
}
stack.push(num);
}
int[] res = new int[nums1.length];
for (int i = 0; i < nums1.length; ++i) {
res[i] = map.getOrDefault(nums1[i], -1);
}
return res;
}
}
  • 上面是左往右遍历,在 while 循环里面弹出元素的时候进行结算。
  • 也可以从右往左遍历,在 while 循环外面进行结算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LeetCode_00496 {

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