单调栈专题练--下一个更大元素

    科技2025-04-19  5

    单调栈,主要用于记录数组中每个元素的下一个更大值。

    为了在O(n)时间复杂度内完成这个目标,需要从后往前维护一个单调递增栈,栈中依次存储当前下一个位置到数组尾的下一个更大值。因此,对于每个位置的更新,只需要从栈中将小值出栈,直到寻找到比当前值大的值即可。

    话不多说直接看题

    1019. Next Greater Node In Linked List

    题意:

    给定一个链表, 对于每个节点,记录链表中下一个比当前节点大的节点值,最终结果用数组返回。

    思路:

    寻找下一个更大节点问题,典型的单调栈问题,首先将链表转化为数组即可直接套单调栈模板

    代码:

    /* Author Owen_Q */ /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: vector<int> nextLargerNodes(ListNode* head) { int n = 0; vector<int> a; while(head!=NULL) { a.push_back(head->val); n++; head = head->next; } vector<int> re(n); stack<int> st; for(int i=n-1;i>=0;i--) { while((!st.empty())&&a[i] >= st.top()) { st.pop(); } if(st.empty()) re[i] = 0; else re[i] = st.top(); st.push(a[i]); } return re; } };

    496. Next Greater Element I

    题意:

    在数组2中寻找数组1中相应值的下一个更大元素

    思路:

    依旧是单调栈问题,只是多了一个数组,那么只需要对数组2进行单调栈维护,并对结果进行hash映射,然后在数组1中进行查找。

    代码:

    /* Author Owen_Q */ class Solution { public: vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) { stack <int> st; int n = nums2.size(); vector<int> re(1e5+7,-1); for(int i=n-1;i>=0;i--) { while((!st.empty())&&nums2[i] >= st.top()) { st.pop(); } if(!st.empty()) re[nums2[i]] = st.top(); st.push(nums2[i]); } vector<int> re1; for(int i:nums1) re1.push_back(re[i]); return re1; } };

    503. Next Greater Element II

    题意:

    循环版下一个更大元素,数组成为了循环数组

    思路:

    只需要维护两轮单调栈即可

    代码:

    /* Author Owen_Q */ class Solution { public: vector<int> nextGreaterElements(vector<int>& nums) { int n = nums.size(); stack <int> st; vector<int> re(n); for(int i=n-1;i>=0;i--) { while((!st.empty())&&nums[i] >= st.top()) st.pop(); if(st.empty()) re[i] = -1; else re[i] = st.top(); st.push(nums[i]); } for(int i=n-1;i>=0;i--) { while((!st.empty())&&nums[i] >= st.top()) st.pop(); if(st.empty()) re[i] = -1; else re[i] = st.top(); st.push(nums[i]); } return re; } };

    739. Daily Temperatures

    题意:

    记录每天温度距离下一次更高温度所相隔的天数

    思路:

    这次记录的不是更大值,而是更大值所在的问题,因此将单调栈中维护的元素从值本身改为位置坐标即可

    代码:

    /* Author Owen_Q */ class Solution { public: vector<int> dailyTemperatures(vector<int>& T) { stack <int> st; int n = T.size(); vector<int> re(n); for(int i=n-1;i>=0;i--) { while((!st.empty())&&T[i] >= T[st.top()]) st.pop(); if(st.empty()) re[i] = 0; else re[i] = st.top() - i; st.push(i); } return re; } };

    此外,对于单调栈的更复杂的运用,感兴趣的朋友可以去体验一下阿里的一道题:

    最大01子矩阵问题(单调栈优化)

    Processed: 0.009, SQL: 8