力扣单调栈算法专题训练

1 专题说明

本博客用来计算力扣上的单调栈题目、解题思路和代码。

在这里插入图片描述

在这里插入图片描述

2 训练

题目1:2866美丽塔II。

解题思路:先计算出prefix[i],表示0~i满足递增情况下,0~i上的元素之和最大值。然后计算出suffix[i],表示i~n-1满足递增情况下,i~n-1上的元素之和最大值。那么以i为峰顶的美丽塔的元素之和的最大值为prefix[i] + suffix[i] - nums[i],遍历i,获得答案即可。

本质上,还是可以归类为:找到i左边,并且<=nums[i]的元素值。

C++代码如下,

class Solution {
   
public:
    long long maximumSumOfHeights(vector<int>& maxHeights) {
   
        int n = maxHeights.size();
        vector<long long> prefix(n, 0); //prefix[i]表示0~i是递增的情况下,0~i的元素之和
        stack<int> stk;
        for (int i = 0; i < n; ++i) {
   
            while (!stk.empty() && maxHeights[stk.top()] > maxHeights[i]) {
   
                stk.pop();
            }
            if (stk.empty()) {
   
                prefix[i] = (long long)(i + 1) * maxHeights[i];
            } else {
   
                prefix[i] = prefix[stk.top()] + (long long)(i - stk.top()) * maxHeights[i];
            }
            stk.push(i);
        }

        while (!stk.empty()) {
   
            stk.pop();
        }

        vector<long long> suffix(n, 0); //suffix[i]表示i~n-1是递减的情况下,i~n-1的元素之和
        for (int i = n - 1; i >= 0; --i) {
   
            while (!stk.empty() && maxHeights[stk.top()] > maxHeights[i]) {
   
                stk.pop();
            }
            if (stk.empty()) {
   
                suffix[i] = (long long)(n - i) * maxHeights[i];
            } else {
   
                suffix[i] = suffix[stk.top()] + (long long)(stk.top() - i) * maxHeights[i];
            }
            stk.push(i);
        }

        long long res = 0;
        for (int i = 0; i < n; ++i) {
   
            res = max(res, prefix[i] + suffix[i] - maxHeights[i]);
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def maximumSumOfHeights(self, maxHeights: List[int]) -> int:
        n = len(maxHeights)
        prefix = [0 for i in range(n)] #0~i的递增数组的和的最大值
        stk = []
        for i in range(n):
            while len(stk) and maxHeights[stk[-1]] > maxHeights[i]:
                del stk[-1]
            if len(stk) == 0:
                prefix[i] = (i + 1) * maxHeights[i]
            else:
                prefix[i] = prefix[stk[-1]] + (i - stk[-1]) * maxHeights[i]
            stk.append(i)
        
        stk.clear()
        suffix = [0 for i in range(n)] #i~n-1的递减数组的和的最大值
        for i in range(n-1,-1,-1):
            while len(stk) and maxHeights[stk[-1]] > maxHeights[i]:
                del stk[-1]
            if len(stk) == 0:
                suffix[i] = (n - i) * maxHeights[i]
            else:
                suffix[i] = suffix[stk[-1]] + (stk[-1] - i) * maxHeights[i]
            stk.append(i)
        
        res = 0
        for i in range(n):
            #print(f"i = {i}, prefix[i] = {prefix[i]}, suffix[i] = {suffix[i]}.")
            res = max(res, prefix[i] + suffix[i] - maxHeights[i])
        return res

题目2:496下一个更大元素I。

解题思路:直接找右边首次大于它的元素即可。

C++代码如下,

class Solution {
   
public:
    vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
   
        unordered_map<int,int> mp; //mp[x]表示nums2中元素x的右边,第一个比它大的元素
        stack<int> stk;
        for (int i = nums2.size() - 1; i >= 0; --i) {
   
            while (!stk.empty() && stk.top() <= nums2[i]) {
   
                stk.pop();
            }
            if (!stk.empty()) {
   
                mp[nums2[i]] = stk.top();
            } else {
   
                mp[nums2[i]] = -1;
            }
            stk.push(nums2[i]);
        }

        vector<int> res;
        for (auto x : nums1) {
   
            res.emplace_back(mp[x]);
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
        n = len(nums2)
        mp = collections.defaultdict(int)
        stk = []
        for i in range(n - 1, -1, -1):
            while len(stk) and stk[-1] <= nums2[i]:
                del stk[-1]
            if len(stk):
                mp[nums2[i]] = stk[-1]
            else:
                mp[nums2[i]] = -1
            stk.append(nums2[i])
        
        res = []
        for x in nums1:
            res.append(mp[x])
        return res 

题目3:503下一个更大元素II。

解题思路:环形问题,扩展两倍原数组即可,接下来就是找右侧首次大于它的元素。

C++代码如下,

class Solution {
   
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
   
        int n = nums.size();
        vector<int> a(2 * n, 0);
        for (int i = 0; i < n; ++i) {
   
            a[i] = a[i + n] = nums[i];
        }

        vector<int> ans(2 * n, -1);
        stack<int> stk;
        for (int i = 2 * n - 1; i >= 0; --i) {
   
            while (!stk.empty() && stk.top() <= a[i]) {
   
                stk.pop();
            }
            if (!stk.empty()) {
   
                ans[i] = stk.top();
            }
            stk.push(a[i]);
        }

        vector<int> res(n, -1);
        for (int i = 0; i < n; ++i) {
   
            res[i] = ans[i];
        }
        return res;
    }
};

python3代码如下,

class Solution:
    def nextGreaterElements(self, nums: List[int]) -> List[int]:
        n = len(nums)
        a = [-1 for i in range(2 * n)]
        for i in range(n):
            a[i] = a[i + n] = nums[i]

        ans = [-1 for i in range(2 * n)]
        stk = []
        for i in range(2 * n - 1, -1, -1):
            while len(stk) and stk[-1] <= a[i]:
                del stk[-1]
            if len(stk):
                ans[i] = stk[-1]
            stk.append(a[i])
        
        res = [-1 for i in range(n)]
        for i in range(n):
            res[i] = ans[i]
        return res 

题目4

相关推荐

  1. 算法37:最大矩形(84、85题)---单调

    2023-12-23 12:46:01       36 阅读
  2. 算法训练营Day59(单调

    2023-12-23 12:46:01       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-23 12:46:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-23 12:46:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-23 12:46:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-23 12:46:01       20 阅读

热门阅读

  1. 《open3D+pyqt》第一章——las格式点云读取

    2023-12-23 12:46:01       42 阅读
  2. SpringMVC系列之技术点定向爆破一

    2023-12-23 12:46:01       40 阅读
  3. vue点击当前盒子以外任意地方隐藏当前盒子

    2023-12-23 12:46:01       41 阅读
  4. 登录接口开发 - 登录注册开发入门(3)

    2023-12-23 12:46:01       47 阅读
  5. js判断是否到T+N的时间限制

    2023-12-23 12:46:01       47 阅读
  6. RK3588 CPHY camera调试(LT7911UXC)

    2023-12-23 12:46:01       61 阅读
  7. JWT 单点登录探析:原理、用途与安全实践

    2023-12-23 12:46:01       41 阅读
  8. B树和B+树的区别

    2023-12-23 12:46:01       41 阅读
  9. 11-Kafka

    11-Kafka

    2023-12-23 12:46:01      35 阅读