news 2026/4/2 23:43:17

算法题 最大宽度坡

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
算法题 最大宽度坡

最大宽度坡

问题描述

给定一个整数数组nums,定义一个为元组(i, j),其中i < jnums[i] <= nums[j]。坡的宽度j - i

请返回数组中最大宽度坡的宽度。如果没有坡,返回 0。

示例

输入: [6,0,8,2,1,5] 输出: 4 解释: 最大宽度坡为 (1, 5): nums[1] = 0 <= nums[5] = 5,宽度 = 5 - 1 = 4 输入: [9,8,1,0,1,9,4,0,4,1] 输出: 7 解释: 最大宽度坡为 (2, 9): nums[2] = 1 <= nums[9] = 1,宽度 = 9 - 2 = 7

算法思路

方法一:暴力

对每个可能的左端点i,遍历所有右端点j > i,检查是否满足nums[i] <= nums[j],并记录最大宽度。

时间复杂度:O(n²),对于 n=50000 会超时。

方法二:单调栈 + 二分搜索

  1. 构建候选左端点:使用单调递减栈存储可能作为左端点的索引

    • 只有当nums[i]小于栈顶元素对应的值时,才将i入栈
    • 保证了栈中索引对应的值是严格递减的
  2. 从右向左寻找右端点:从数组末尾开始遍历,对每个位置j

    • 在单调栈中找到最左边的索引i,使得nums[i] <= nums[j]
    • 由于栈中值是递减的,可以使用二分搜索快速定位

代码实现

方法一:暴力

classSolution{/** * 暴力:检查所有可能的坡 * * @param nums 输入数组 * @return 最大宽度坡的宽度 */publicintmaxWidthRamp(int[]nums){intmaxRamp=0;intn=nums.length;for(inti=0;i<n;i++){for(intj=i+1;j<n;j++){if(nums[i]<=nums[j]){maxRamp=Math.max(maxRamp,j-i);}}}returnmaxRamp;}}

方法二:单调栈 + 二分搜索

importjava.util.*;classSolution{/** * 使用单调栈和二分搜索求解最大宽度坡 * * @param nums 输入数组 * @return 最大宽度坡的宽度 */publicintmaxWidthRamp(int[]nums){intn=nums.length;Stack<Integer>stack=newStack<>();// 构建单调递减栈,存储候选左端点的索引// 栈中索引对应的值是严格递减的for(inti=0;i<n;i++){// 只有当当前元素小于栈顶元素对应的值时才入栈if(stack.isEmpty()||nums[i]<nums[stack.peek()]){stack.push(i);}}intmaxRamp=0;// 从右向左遍历,寻找最佳右端点for(intj=n-1;j>=0;j--){// 在单调栈中找到最左边的索引i,使得nums[i] <= nums[j]// 由于栈中值递减,可以弹出所有满足条件的栈顶元素while(!stack.isEmpty()&&nums[stack.peek()]<=nums[j]){inti=stack.pop();maxRamp=Math.max(maxRamp,j-i);}}returnmaxRamp;}}

算法分析

方法一:暴力

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)

方法二:单调栈 + 二分搜索

  • 时间复杂度:O(n)
    • 构建单调栈:O(n)
    • 从右向左遍历:O(n)
    • 每个元素最多入栈和出栈一次
  • 空间复杂度:O(n)
    • 单调栈最多存储 n 个元素

算法过程

输入[9,8,1,0,1,9,4,0,4,1]

1:构建单调递减栈

  • i=0: stack=[0] (值9)
  • i=1: 8<9, stack=[0,1] (值9,8)
  • i=2: 1<8, stack=[0,1,2] (值9,8,1)
  • i=3: 0<1, stack=[0,1,2,3] (值9,8,1,0)
  • i=4: 1>0, 跳过
  • i=5: 9>0, 跳过
  • i=6: 4>0, 跳过
  • i=7: 0==0, 跳过
  • i=8: 4>0, 跳过
  • i=9: 1>0, 跳过

最终栈:[0,1,2,3] 对应值 [9,8,1,0]

2:从右向左遍历找最大坡

  • j=9, nums[9]=1:
    • 比较栈顶 nums[3]=0 ≤ 1 , 宽度=9-3=6, maxRamp=6
    • 比较栈顶 nums[2]=1 ≤ 1 , 宽度=9-2=7, maxRamp=7
    • 比较栈顶 nums[1]=8 > 1 , 停止
  • j=8, nums[8]=4:
    • 比较栈顶 nums[1]=8 > 4 , 跳过
  • j=7, nums[7]=0:
    • 比较栈顶 nums[1]=8 > 0 , 跳过
  • j=6, nums[6]=4:
    • 比较栈顶 nums[1]=8 > 4 , 跳过
  • j=5, nums[5]=9:
    • 比较栈顶 nums[1]=8 ≤ 9 , 宽度=5-1=4, maxRamp=7
    • 比较栈顶 nums[0]=9 ≤ 9 , 宽度=5-0=5, maxRamp=7
    • 栈空,停止

最终结果:7

测试用例

publicclassTestMaxWidthRamp{publicstaticvoidmain(String[]args){Solutionsolution=newSolution();// 测试用例1:基本示例int[]nums1={6,0,8,2,1,5};System.out.println("Test 1: "+solution.maxWidthRamp(nums1));// 4// 测试用例2:复杂示例int[]nums2={9,8,1,0,1,9,4,0,4,1};System.out.println("Test 2: "+solution.maxWidthRamp(nums2));// 7// 测试用例3:严格递减数组(无坡)int[]nums3={9,8,7,6,5,4,3,2,1,0};System.out.println("Test 3: "+solution.maxWidthRamp(nums3));// 0// 测试用例4:严格递增数组int[]nums4={0,1,2,3,4,5,6,7,8,9};System.out.println("Test 4: "+solution.maxWidthRamp(nums4));// 9// 测试用例5:所有元素相同int[]nums5={5,5,5,5,5};System.out.println("Test 5: "+solution.maxWidthRamp(nums5));// 4// 测试用例6:单元素int[]nums6={1};System.out.println("Test 6: "+solution.maxWidthRamp(nums6));// 0// 测试用例7:两元素递增int[]nums7={1,2};System.out.println("Test 7: "+solution.maxWidthRamp(nums7));// 1// 测试用例8:两元素递减int[]nums8={2,1};System.out.println("Test 8: "+solution.maxWidthRamp(nums8));// 0}}

关键点

  1. 单调栈

    • 过滤掉"无用"的左端点
    • 保证栈中候选左端点的值严格递减
    • 使得后续查找更高效
  2. 为什么从右向左遍历

    • 对于固定的左端点,希望右端点尽可能靠右
    • 从右向左遍历可以确保找到每个左端点对应的最佳右端点
  3. 边界情况处理

    • 严格递减数组:返回0
    • 严格递增数组:返回n-1
    • 所有元素相同:返回n-1

常见问题

  1. 为什么单调栈要维护递减序列?

    • 如果存在i1 < i2nums[i1] <= nums[i2],那么i2永远不会成为最优左端点
    • i1位置更靠左,值更小或相等,对于任何右端点j,如果(i2,j)是坡,那么(i1,j)也是坡且宽度更大
  2. 能否从左向右遍历找右端点?

    • 效率较低
    • 从右向左遍历可以利用贪心思想:一旦找到满足条件的左端点,就可以立即计算宽度
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/21 7:46:45

VibeThinker-1.5B代码生成避坑:常见错误输出及修正方法

VibeThinker-1.5B代码生成避坑&#xff1a;常见错误输出及修正方法 VibeThinker-1.5B-WEBUI 提供了一个简洁直观的交互界面&#xff0c;让用户可以快速进行代码生成和数学推理任务。通过浏览器即可完成输入与结果查看&#xff0c;特别适合开发者、算法爱好者在本地或云端环境中…

作者头像 李华
网站建设 2026/3/28 2:37:40

Z-Image-Turbo权限管理:限制访问保障模型安全使用

Z-Image-Turbo权限管理&#xff1a;限制访问保障模型安全使用 Z-Image-Turbo 是一款功能强大的图像生成模型&#xff0c;其配套的 UI 界面让使用者能够通过可视化操作快速完成图像生成任务。整个界面设计简洁直观&#xff0c;主要包含提示词输入区、参数调节滑块、生成按钮以及…

作者头像 李华
网站建设 2026/3/24 1:12:04

全栈突围:智谱GLM-Image × 昇腾·昇思携手走出“无人区”

技术只有变得足够“便宜”&#xff0c;才能实现真正“普及”&#xff0c;从而深度融入到工作与生活的方方面面。所以&#xff0c;当GLM-Image在API调用模式下生成一张图片只需0.1元时&#xff0c;价格仅为海外同类产品的1/10至1/3&#xff0c;全球AI市场都为之震撼。GLM-Image是…

作者头像 李华
网站建设 2026/3/21 4:20:54

【快速EI检索 | 高录用 | EI检索稳定 | 对学生友好会议 | JPCS出版有ISSN号,高录用,见刊快】2026年航空航天、智能感知与控制国际学术会议

2026年航空航天、智能感知与控制国际学术会议 2026 International Conference on Aerospace, Intelligent Perception and Control (AIPC 2026) 2026年2月6日-2月8日 &#xff5c;中国-昆明 大会官网&#xff1a;www.icaipc.org 截稿时间&#xff1a;见官网&#xff08;早投…

作者头像 李华
网站建设 2026/3/22 1:53:45

吃透这 5 个 C/C++ 就业方向,应届生也能拿高薪 Offer

如果你现在正为 C 开发方向感到迷茫&#xff0c;不知道该往哪走&#xff0c;那这篇内容或许能给你一些思路。 相信我&#xff0c;几年后再回头看&#xff0c;你一定会感激此刻为方向努力探索的自己。 C 作为当下依然主流的面向对象语言&#xff0c;应用场景非常广泛 —— 总有…

作者头像 李华
网站建设 2026/3/19 18:42:59

PostgreSQL 性能:云端与本地的延迟分析

PostgreSQL 在各行各业的关键应用中具有极高适用性。尽管 PostgreSQL 提供了良好的性能&#xff0c;但仍存在一些用户不太关注但对整体效率与速度至关重要的问题。多数人认为增加 CPU 核数、更快的存储、更大内存即可提升性能&#xff0c;但还有同样重要的因素需要关注——那就…

作者头像 李华