• 代码随想录笔记--单调栈篇


    目录

    1--单调栈

    2--每日温度

    3--下一个更大元素I

    3--下一个更大元素II

    4--接雨水

    5--柱状图中最大的矩形


    1--单调栈

            使用单调栈的特征:寻找第一个比当前元素大或者小的元素。

            当题目要求寻找左右第一个比当前栈顶元素大的元素时,使用单调递增的单调栈(从栈顶开始);

            当题目要求寻找左右第一个比当前栈顶元素小的元素时,使用单调递减的单调栈(从栈顶开始);

    2--每日温度

    主要思路:

            基于单调栈,单调栈从栈顶开始递增;单调栈存储的是元素对应的索引。

            当遇到一个元素大于栈顶元素i时,计算 answer[i]。

    1. #include
    2. #include
    3. #include
    4. class Solution {
    5. public:
    6. std::vector<int> dailyTemperatures(std::vector<int>& temperatures) {
    7. std::vector<int> res(temperatures.size(), 0);
    8. std::stack<int> stk;
    9. for(int i = 0; i < temperatures.size(); i++){
    10. while(!stk.empty() && temperatures[i] > temperatures[stk.top()]){
    11. res[stk.top()] = i - stk.top();
    12. stk.pop();
    13. }
    14. stk.push(i);
    15. }
    16. return res;
    17. }
    18. };
    19. int main(int argc, char* argv[]){
    20. // temperatures = [73,74,75,71,69,72,76,73]
    21. std::vector<int> test = {73, 74, 75, 71, 69, 72, 76, 73};
    22. Solution S1;
    23. std::vector<int> res = S1.dailyTemperatures(test);
    24. for(auto num : res) std::cout << num << " ";
    25. std::cout << std::endl;
    26. return 0;
    27. }

    3--下一个更大元素I

    主要思路:

            基于单调栈和哈希表。

            将 nums1 的元素映射为哈希表,其中 key 为 num1[i],val 为 i;

            遍历 nums2 构建单调栈,当 nums2[i] > stk.top() 时,且 stk.top() 属于 nums1,表明找到第一个比它大的元素,则根据hash_map[stk.top()]可以知道其在nums1的位置,记录结果res[hash_map[stk.top()]] = nums2[i] 即可。

    1. #include
    2. #include
    3. #include
    4. #include
    5. class Solution {
    6. public:
    7. std::vector<int> nextGreaterElement(std::vector<int>& nums1, std::vector<int>& nums2) {
    8. std::vector<int> res(nums1.size(), -1);
    9. if(nums1.size() == 0) return res;
    10. std::unordered_map<int, int>hash_map;
    11. for(int i = 0; i < nums1.size(); i++) hash_map.emplace(nums1[i], i); // 存储值,索引
    12. std::stack<int> stk;
    13. for(int i = 0; i < nums2.size(); i++){
    14. while(!stk.empty() && nums2[i] > stk.top()){
    15. if(hash_map.find(stk.top()) != hash_map.end()){
    16. res[hash_map[stk.top()]] = nums2[i];
    17. }
    18. stk.pop();
    19. }
    20. stk.push(nums2[i]);
    21. }
    22. return res;
    23. }
    24. };
    25. int main(int argc, char* argv[]){
    26. // nums1 = [4,1,2], nums2 = [1,3,4,2]
    27. std::vector<int> test1 = {4, 1, 2};
    28. std::vector<int> test2 = {1, 3, 4, 2};
    29. Solution S1;
    30. std::vector<int> res = S1.nextGreaterElement(test1, test2);
    31. for(auto num : res) std::cout << num << " ";
    32. std::cout << std::endl;
    33. return 0;
    34. }

    3--下一个更大元素II

    主要思路:

            基于单调栈,本题的难点是针对一个循环数组,可以通过取模的操作来模拟循环数组。

    1. #include
    2. #include
    3. #include
    4. class Solution {
    5. public:
    6. std::vector<int> nextGreaterElements(std::vector<int>& nums) {
    7. std::vector<int> res(nums.size(), -1);
    8. std::stack<int> stk;
    9. for(int i = 0; i < 2*nums.size(); i++){
    10. // 通过取模操作模拟有环的过程
    11. int idx = i % nums.size();
    12. while(!stk.empty() && nums[idx] > nums[stk.top()]){
    13. res[stk.top()] = nums[idx];
    14. stk.pop();
    15. }
    16. stk.push(idx);
    17. }
    18. return res;
    19. }
    20. };
    21. int main(int argc, char* argv[]){
    22. // nums = [1, 2, 1]
    23. std::vector<int> test = {1, 2, 1};
    24. Solution S1;
    25. std::vector<int> res = S1.nextGreaterElements(test);
    26. for(int num : res) std::cout << num << " ";
    27. std::cout << std::endl;
    28. return 0;
    29. }

    4--接雨水

    主要思路:

            维护一个单调递增的单调栈(从栈顶开始)。当某一个元素比当前栈顶元素大时,计算以该栈顶元素为中心的接雨水面积:area = (当前遍历元素的索引 - 栈顶元素栈中前一个元素的索引)* min(当前遍历元素的高度 - 栈顶元素的高度,栈顶元素栈中前一个元素的高度 - 栈顶元素的高度)

    1. #include
    2. #include
    3. #include
    4. class Solution {
    5. public:
    6. int trap(std::vector<int>& height) {
    7. std::stack<int> stk;
    8. int res = 0;
    9. for(int i = 0; i < height.size(); i++){
    10. while(!stk.empty() && height[i] > height[stk.top()]){
    11. int top_h = height[stk.top()]; // 栈顶元素高度
    12. stk.pop();
    13. if(!stk.empty()){
    14. res += (i - stk.top() - 1) * std::min(height[i] - top_h, height[stk.top()] - top_h);
    15. }
    16. }
    17. stk.push(i);
    18. }
    19. return res;
    20. }
    21. };
    22. int main(int argc, char* argv[]){
    23. // height = [4, 2, 0, 3, 2, 5]
    24. std::vector<int> test = {4, 2, 0, 3, 2, 5};
    25. Solution S1;
    26. int res = S1.trap(test);
    27. std::cout << res << std::endl;
    28. return 0;
    29. }

    5--柱状图中最大的矩形

    主要思路:

            维护一个单调递减的单调栈(从栈顶开始),对于每一个柱子,寻找左右两边比其高度矮的柱子,计算其构成的矩形面积: area = (当前遍历元素的索引 - 栈顶元素在栈中上一个元素的索引 - 1)* 当前栈顶元素的高度;

    1. #include
    2. #include
    3. #include
    4. class Solution {
    5. public:
    6. int largestRectangleArea(std::vector<int>& heights){
    7. int res = 0;
    8. std::stack<int> stk;
    9. heights.insert(heights.begin(), 0);
    10. heights.insert(heights.end(), 0);
    11. for(int i = 0; i < heights.size(); i++){
    12. while(!stk.empty() && heights[i] < heights[stk.top()]){
    13. int cur_idx = stk.top();
    14. stk.pop();
    15. if(!stk.empty()){
    16. res = std::max(res, (i - stk.top() - 1)*heights[cur_idx]);
    17. }
    18. }
    19. stk.push(i);
    20. }
    21. return res;
    22. }
    23. };
    24. int main(int argc, char* argv[]){
    25. // heights = [2, 1, 5, 6, 2, 3]
    26. std::vector<int> test = {2, 1, 5, 6, 2, 3};
    27. Solution S1;
    28. int res = S1.largestRectangleArea(test);
    29. std::cout << res << std::endl;
    30. return 0;
    31. }

    代码随想录 ended in 2023.10.24 !!!

  • 相关阅读:
    Android开发基础——Activity启动模式
    C语言快速排序
    服务发现原理分析与源码解读
    Hadoop HA (二) --------- HDFS-HA 手动模式
    C陷阱——数组越界引发的死循环问题
    SwiftUI 导航设置
    面试高频的ES6中的Map和Set数据结构详解
    【淘宝API】商品详情+搜索商品列表接口
    HDU_1018
    测试用例的基本要素 && properties配置文件 && 测试用例的基本要素 && SpringMVC背景知识 && 按照开发阶段划分测试类型
  • 原文地址:https://blog.csdn.net/weixin_43863869/article/details/133987977