# Monotonic stack(單調棧/單調陣列) Host - Al Master - Jack Interviewer - Brian Candidate - Lyndon ## Mock Interview https://docs.google.com/document/d/11sALw-uUXmNrhpTEvFDsFgs1jze90TVloHfP1kB30XI/edit ## 重點 1. 單調棧是用來找尋鄰近的元素 單調棧不僅用於確定數組的單調性,更多的是用來解決找尋與數組中元素鄰近的問題,例如尋找某元素右側的第一個比它大或小的元素。 2. 單調棧在推入元素時會維持其遞增或遞減的性質 當元素進入棧時,單調棧會通過不斷的彈出棧頂元素來確保它維持遞增或遞減的性質。 ### 舉例來說 假設我們有一個數組 [2, 1, 3, 4, 0] 我們想知道每個元素右邊的第一個比它小的元素。 對於元素 2,它右邊的第一個比它小的元素是 1。 對於元素 1,它右邊沒有比它小的元素。 對於元素 3,它右邊的第一個比它小的元素是 0。 對於元素 4,它右邊的第一個比它小的元素是 0。 對於元素 0,它右邊沒有元素。 使用單調棧,我們可以簡單地得到答案為 [1,0,0,0,−1] ### 模板 以 nextSmaller 舉例 ```=! std::vector<int> nextSmallerElement(const std::vector<int>& nums) { std::vector<int> result(nums.size(), -1); std::stack<int> s; // 存儲元素索引的單調棧 for (int i = 0; i < nums.size(); ++i) { while (!s.empty() && nums[i] < nums[s.top()]) { int idx = s.top(); s.pop(); result[idx] = i; } s.push(i); } return result; } ``` ## 使用 deque 的單調隊列/棧 當我們討論單調棧時,實際上我們通常指的是一種特殊的數據結構,它在底層可以使用堆疊或隊列來實現。在某些情況下,使用雙端隊列 (deque) 作為底層結構會更加方便,因為它允許我們在前端和後端同時進行操作。 ### 基本概念 單調隊列是一種數據結構,它可以在任一端插入或刪除元素,同時保持其內部元素的單調性(遞增或遞減)。 ### 使用場景 滑動窗口中的最大/最小值問題。 某些需要快速找到當前元素之前/之後的最大/最小值的問題。 ```=! #include <iostream> #include <vector> #include <deque> std::vector<int> slidingWindowMin(const std::vector<int>& nums, int k) { std::deque<int> dq; // 存儲元素索引的單調隊列 std::vector<int> result; for (int i = 0; i < nums.size(); ++i) { // 移除超出窗口的索引 while (!dq.empty() && dq.front() < i - k + 1) { dq.pop_front(); } // 維持隊列的單調性 while (!dq.empty() && nums[i] <= nums[dq.back()]) { dq.pop_back(); } dq.push_back(i); if (i >= k - 1) { result.push_back(nums[dq.front()]); } } return result; } int main() { std::vector<int> nums = {1, 3, -1, -3, 5, 3, 6, 7}; int k = 3; std::vector<int> result = slidingWindowMin(nums, k); for (int val : result) { std::cout << val << " "; } return 0; } ``` ## 練習 [496. Next Greater Element I ](https://leetcode.com/problems/next-greater-element-i/) =>[解答](https://hackmd.io/@jacklee20499/r1rYVakg6) [739. Daily Temperatures](https://leetcode.com/problems/daily-temperatures/)=>[解答](https://hackmd.io/@jacklee20499/HkBvtSB0h) [84. Largest Rectangle in Histogram](https://leetcode.com/problems/largest-rectangle-in-histogram/)=>[解答](https://hackmd.io/@jacklee20499/BJHqmnWkT) [239. Sliding Window Maximum](https://leetcode.com/problems/sliding-window-maximum/)=>[解答](https://hackmd.io/@jacklee20499/r1amQrB16) ## 題目 [42. Trapping Rain Water](https://leetcode.com/problems/trapping-rain-water/) =>[解答](https://hackmd.io/@jacklee20499/BkQJl6ACn) [856. Score of Parentheses](https://leetcode.com/problems/score-of-parentheses/) =>[解答](https://hackmd.io/@jacklee20499/HJtp4Jgl6) [901. Online Stock Span](https://leetcode.com/problems/online-stock-span/) =>[解答](https://hackmd.io/@jacklee20499/ry34FzxxT) [907. Sum of Subarray Minimums](https://leetcode.com/problems/sum-of-subarray-minimums/) =>[解答](https://hackmd.io/@jacklee20499/r1Gv9zeeT) [1130. Minimum Cost Tree From Leaf Values](https://leetcode.com/problems/minimum-cost-tree-from-leaf-values/) =>[解答](https://hackmd.io/@jacklee20499/rJvdUz-ea) [1425. Constrained Subsequence Sum](https://leetcode.com/problems/constrained-subsequence-sum/) =>[解答](https://hackmd.io/@jacklee20499/B12loDzga) [1475. Final Prices With a Special Discount in a Shop](https://leetcode.com/problems/final-prices-with-a-special-discount-in-a-shop/) =>[解答](https://hackmd.io/@jacklee20499/rJCCdwGep) [1671. Minimum Number of Removals to Make Mountain Array](https://leetcode.com/problems/minimum-number-of-removals-to-make-mountain-array/) =>[解答](https://hackmd.io/@jacklee20499/r1beAcMlT) [1673. Find the Most Competitive Subsequence](https://leetcode.com/problems/find-the-most-competitive-subsequence/) =>[解答](https://hackmd.io/@jacklee20499/rkS7pWQgp) [1776. Car Fleet II](https://leetcode.com/problems/car-fleet-ii/) =>[解答](https://hackmd.io/@jacklee20499/HyJF98Xg6) [2281. Sum of Total Strength of Wizards](https://leetcode.com/problems/sum-of-total-strength-of-wizards/) =>[解答](https://hackmd.io/@jacklee20499/rkdzk07eT) [2289. Steps to Make Array Non-decreasing](https://leetcode.com/problems/steps-to-make-array-non-decreasing/) =>[解答](https://hackmd.io/@jacklee20499/SkO83zSlp) [2398. Maximum Number of Robots Within Budget](https://leetcode.com/problems/maximum-number-of-robots-within-budget/) =>[解答](https://hackmd.io/@jacklee20499/rJgWLQBg6) [2454. Next Greater Element IV](https://leetcode.com/problems/next-greater-element-iv/) =>[解答](https://hackmd.io/@jacklee20499/rksxOVrea) [2735. Collecting Chocolates](https://leetcode.com/problems/collecting-chocolates/) =>[解答](https://hackmd.io/@jacklee20499/r1FiNsLea) [2866. Beautiful Towers II](https://leetcode.com/problems/beautiful-towers-ii/) =>[解答](https://hackmd.io/@jacklee20499/HkqCm3keT)