• 【C语言刷LeetCode】1962. 最大宽度坡(M)


    给定一个整数数组 A,坡是元组 (i, j),其中  i < j 且 A[i] <= A[j]。这样的坡的宽度为 j - i。

    找出 A 中的坡的最大宽度,如果不存在,返回 0 。

    示例 1:

    输入:[6,0,8,2,1,5]
    输出:4
    解释:
    最大宽度的坡为 (i, j) = (1, 5): A[1] = 0 且 A[5] = 5.
    示例 2:

    输入:[9,8,1,0,1,9,4,0,4,1]
    输出:7
    解释:
    最大宽度的坡为 (i, j) = (2, 9): A[2] = 1 且 A[9] = 1.
     

    提示:

    2 <= A.length <= 50000
    0 <= A[i] <= 50000

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/maximum-width-ramp
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    这道题一开始想到单调栈,但想到的是单调递增栈,那如何存放最小值和最大值呢?每次来一个元素就把它放到对应位置,那么索引又该如何处理?想不通了。

    但试试单调递减栈呢?

    来自作者Booooo_的解释:

    首先正序遍历数组 A,将以 A[0] 开始的递减序列的元素下标依次存入栈中。
    为什么要存从 A[0] 开始的递减序列呢?
    因为题中条件 A[i] <= A[j],所以要让 A[i] 的值尽可能的小,即从 A[0] 开始的一个递减序列。单调栈中记录的是从后往前每个大分段 “坡底” 所在的位置。
    以 [6, 1, 8, 2, 0, 5] 为例,由于 (6, 1, 0) 是递减的,所以栈中存的元素应该为:(栈顶 -> (4, 1, 0) <- 栈底)。
    其中 [2, 0, 5] 也是一个满足条件的坡并且宽度为 2,但是为什么在计算的时候没有算它呢?
    因为该数组从 A[0] 开始的递减序列为 (6, 1, 0) 并没有元素 2,是因为在元素 2 的左边有比它还要小的元素 1。当计算最大宽度坡时 1 和 2 相比,不管是元素值还是元素的下标都更小,所以若以 2 为坡底能计算出某一坡的宽度时同样的以 1 为坡底也能计算出相应的坡的宽度并且宽度更大,所以就不需要计算以 2 为坡底的坡的宽度了。
    此时栈 stack:(4(0), 1(1), 0(6)):然后逆序遍历数组 A,若以栈顶元素为下标的元素值 A[stack.peek()] 小于等于当前遍历的元素 A[i],即 A[stack.peek()] <= A[i]。此时就是一个满足条件的坡的宽度,并且这个宽度一定是栈顶这个坡底 i 能形成的最大宽度,将栈顶元素出栈并计算当前坡的宽度,保留最大值即可。

    代码如下:

    1. // 一个非标准的单调栈问题
    2. int maxWidthRamp(int* nums, int numsSize){
    3. int ret = 0;
    4. int stack[50000] = {0};
    5. int idx = 0;
    6. stack[idx] = 0; // 存入第一个元素
    7. // 先找个递减栈,stack[idx]存的索引
    8. for (int i = 1; i < numsSize; i++) {
    9. if (nums[stack[idx]] > nums[i]) {
    10. stack[++idx] = i; // 注意是 ++idx,而不是 idx++
    11. }
    12. }
    13. // 逆序开始比较
    14. for (int j = numsSize - 1; j >= 0; j--) {
    15. while ((idx >= 0) && (nums[j] >= nums[stack[idx]])) { // 要判断 idx 不要到 -1了, while 循环
    16. ret = fmax(ret, j - stack[idx]); // j - stack[idx],注意不是 j - idx
    17. idx--;
    18. }
    19. if (idx < 0) { // 还是要防止 idx 不要到 -1
    20. break;
    21. }
    22. }
    23. return ret;
    24. }

  • 相关阅读:
    第6周学习:Vision Transformer & Swin Transformer
    GPU服务器安装驱动、cuda和cudnn和tensorflow
    基于python的毕业设计电脑硬件配置推荐系统
    PMP每日一练 | 考试不迷路-8.10(包含敏捷+多选)
    Three.js对模型进行多区域染色
    Spring整合其他技术
    Java List.sort()的使用 和Comparator转换器的实现原理
    项目总结(制作报表)
    Windows OpenGL 波浪特效
    k8s k3s节点加入控制平面没效果
  • 原文地址:https://blog.csdn.net/jin615567975/article/details/125493875