下一个更大元素-i
Tips
题目
给你两个没有重复元素的数组 nums1 和 nums2, 其中 nums1 是 nums2 的子集.
请你找出 nums1 中每个元素在 nums2 中的下一个比其大的值.
nums1 中数字 x 的下一个更大元素是指 x 在 nums2 中对应位置的右边的第一个比 x 大的元素. 如果不存在, 对应位置输出 -1.
示例
输入: nums1 = [4, 1, 2], nums2 = [1, 3, 4, 2].
输出: [-1, 3, -1]
解释:
对于 num1 中的数字 4, 你无法在第二个数组中找到下一个更大的数字(4 在 nums2 的右边只有 2 了), 因此输出 -1.
对于 num1 中的数字 1, 第二个数组中数字 1 右边的下一个较大数字是 3.
对于 num1 中的数字 2, 第二个数组中没有下一个更大的数字, 因此输出 -1.
题解
TIPS
单调栈实际上就是栈, 使得每次新元素入栈后, 栈内的元素都保持有序(单调递增或单调递减).
下面这个图很有启发, 把数组的元素想象成并列站立的人, 元素大小想象成人的身高. 以第一个 2 元素为例, 向后看去, 后面的 1 和 2 全被遮住了, 你只能看到 4, 因此 2 对应的下一个更大元素就是 4; 同理第二个元素 1 向后看去, 最先能看到 2, 因此 1 对应的下一个更大元素就是 2.
- 暴力解法
- 单调栈 - JavaScript
- 单调栈 - Rust
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var nextGreaterElement = function (nums1, nums2) {
const result = new Array(nums1.length).fill(-1)
for (let i = 0; i < nums1.length; i++) {
for (let j = 0; j < nums2.length; j++) {
if (nums2[j] === nums1[i]) {
for (k = j + 1; k < nums2.length; k++) {
if (nums2[k] > nums1[i]) {
result[i] = nums2[k]
break
}
}
}
}
}
return result
}
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number[]}
*/
var nextGreaterElement = function (nums1, nums2) {
const map = new Map()
const stack = []
for (const num of nums2) {
while (stack.length > 0 && stack[stack.length - 1] < num) {
map.set(stack.pop(), num)
}
stack.push(num)
}
const n = nums1.length
const res = new Array(n).fill(-1)
for (let i = 0; i < n; i++) {
if (map.has(nums1[i])) {
res[i] = map.get(nums1[i])
}
}
return res
}
use std::collections::HashMap;
pub fn next_greater_element(nums1: Vec<i32>, nums2: Vec<i32>) -> Vec<i32> {
let mut map = HashMap::new();
let mut stack = vec![];
for num in nums2 {
while !stack.is_empty() && stack[stack.len() - 1] < num {
map.entry(stack[stack.len() - 1])
.and_modify(|e| *e = num)
.or_insert(num);
stack.pop();
}
stack.push(num);
}
let mut res = vec![-1; nums1.len()];
for (i, num) in nums1.iter().enumerate() {
if let Some(x) = map.get(&num) {
res[i] = *x;
}
}
res
}