LeetCode 496 Next Greater Element I
概述
https://leetcode.com/problems/next-greater-element-i/
对于这种要运行多次的算法,我们需要建立一个数据结构来快速查询。
直接法
每次直接遍历,时间复杂度 O(mn),m 和 n 分别是两个数组的个数。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
vector<int> res;
for (auto i : nums1) {
int t = -1;
int found = false;
for (auto j : nums2) {
if (!found && j == i) found = true;
if (found && j > i) {
t = j;
break;
}
}
res.push_back(t);
}
return res;
}
};
基于单调栈的解法
https://labuladong.gitee.io/algo/2/20/51/
对于一个元素的下一个较大值,其答案必然仅存在其后面的元素中,因此我们应当反向遍历
然后我们需要维护一个数据结构用来存储有用的遍历过的值,新值加入后,那些没其大的旧值就可以淘汰掉了,因为其必然被挡住。
所以我们需要维护一个单调栈。
由于每个元素最多 push 一次,所以 while 循环最多运行 n 次,所以是 O(n) 的时间复杂度,n 为 num2 元素个数。
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> cache;
stack<int> s;
for (int i = nums2.size() - 1; i >= 0; i --) {
while (!s.empty() && s.top() <= nums2[i]) {
s.pop();
}
if (!s.empty()) {
cache[nums2[i]] = s.top();
}
s.push(nums2[i]);
}
vector<int> ans(nums1.size() , -1);
for (int i = 0; i < nums1.size(); i ++) {
if (cache.count(nums1[i])) ans[i] = cache[nums1[i]];
}
return ans;
}
};