读完本文章,你可以去LeetCode上拿下下面两个题目!!!
496.下一个更大元素I(单调栈+map) 503.下一个更大元素II
单调栈解决 Next Greater Number 问题
Next Greater Number原始问题
给你一个数组,返回一个等长数组,对应索引存储着下一个更大的元素,若没有更大元素,就存-1。
- 例:给你一个数组[2,1,2,4,3],你需要返回数组[4,2,4,-1,-1]
- 解释:第一个2后面比2大的数是4,1后面比1大的数是2,第二个 2 后面比 2 大的数是 4; 4 后面没有比 4 大的数,填 -1;3 后面没有比 3 大的数,填 -1。
解题思路
暴力法
暴力法就是对每个元素后面进行遍历,找到第一个更大的元素存到返回数组中,没有更大的就存-1,详细代码不展示。
单调栈法
首先我们进行抽象思考:我们将数组的元素看成站立在一排的人,元素大小就是人的身高,问题就抽象为每个人能看到第一个比自己高的人的身高,没有比自己高的人话,就是-1。 这样应该让大家更好的理解了!下面根据代码讲解
vector<int> nextGreaterElement(vector<int>& nums) {
vector<int> rs(nums.size());
stack<int> s;
for (int i = nums.size() - 1; i >= 0; i--) {
while (!s.empty() && s.top() <= nums[i]) {
s.pop();
}
rs[i] = s.empty() ? -1 : s.top();
s.push(nums[i]);
}
return rs;
}
- 如何更高效地计算nums中每个元素右边的第一个更大的值?
- 倒序遍历nums,并用单调栈维护当前位置右边的更大的元素列表,从栈底到栈顶的元素是单调递减的。
- 每次我们移动到数组中一个新的位置 i,就将当前单调栈中所有小于 nums[i]的元素弹出单调栈,当前位置右边的第一个更大的元素即为栈顶元素。
- 如果栈为空则说明当前位置右边没有更大的元素,存入-1,否则存入栈顶元素。
- 然后将当前元素入栈,i–往前移动继续上述步骤,直到遍历完为止。
(进阶)循环数组——下一个更大元素问题
解题思路
- 思路同前面讲解例题一致。只是数组是进行循环的。
- 例: 给你一个数组 [2,1,2,4,3],你返回数组 [4,2,4,-1,4]。
- 拥有了环形属性,最后一个元素 3 绕了一圈后找到了比自己大的元素 4 。
- 我们将数组长度放大一倍,对下标进行取模得到下标来达到循环的效果。
这样应该让大家更好的理解了!下面根据代码讲解
vector<int> nextGreaterElements(vector<int>& nums) {
int n = nums.size();
vector<int> rs(n);
stack<int> s;
for (int i = 2 * n - 1; i >= 0; i--) {
while (!s.empty() && s.top() <= nums[i % n])
s.pop();
rs[i % n] = s.empty() ? -1 : s.top();
s.push(nums[i % n]);
}
return rs;
}
力扣相关例题
496.下一个更大元素I(单调栈+map) 503.下一个更大元素II
以上两个题和上述的思路一样,请大家试试!!!
|