当前位置: 首页 > news >正文

展示网站如何做公司营销外包

展示网站如何做,公司营销外包,网站做淘宝客收入咋样,五个跨境电商平台单调栈一文深度解析 一、单调栈基础概念1.1 定义与核心特性1.2 与普通栈的区别1.3 核心操作模板 二、单调栈核心原理2.1 单调性维护机制2.2 典型应用场景 三、经典案例解析下一个更大元素问题描述思路分析代码实现复杂度分析 接雨水问题问题描述思路分析代码实现复杂度分析 柱状…

单调栈一文深度解析

    • 一、单调栈基础概念
      • 1.1 定义与核心特性
      • 1.2 与普通栈的区别
      • 1.3 核心操作模板
    • 二、单调栈核心原理
      • 2.1 单调性维护机制
      • 2.2 典型应用场景
    • 三、经典案例解析
      • 下一个更大元素
        • 问题描述
        • 思路分析
        • 代码实现
        • 复杂度分析
      • 接雨水问题
        • 问题描述
        • 思路分析
        • 代码实现
        • 复杂度分析
      • 柱状图最大面积
        • 问题描述
        • 思路分析
        • 代码实现
        • 复杂度分析
    • 四、单调栈解题模板
      • 4.1 通用解题步骤
      • 4.2 常见问题映射表
    • 五、进阶技巧与优化
      • 5.1 双向单调栈
      • 5.2 单调栈与动态规划结合
      • 5.3 注意事项

单调栈是一种专门处理元素间序关系的高效数据结构,它通过维护栈内元素的单调性,能够在线性时间内解决诸如下一个更大/小元素系列经典问题。本文我将从单调栈的核心原理出发,结合经典案例,解析并总结其解题模板及优化技巧,帮你掌握这一高效解题工具。

一、单调栈基础概念

1.1 定义与核心特性

单调栈是指栈内元素(从栈底到栈顶)保持单调递增或单调递减的栈结构。根据单调性不同,分为:

  • 单调递增栈:栈内元素始终满足 stack[i] <= stack[i+1]
  • 单调递减栈:栈内元素始终满足 stack[i] >= stack[i+1]

其核心特性是:当新元素入栈时,通过弹出栈顶不满足单调性的元素,确保栈内元素始终保持单调。这种特性使得单调栈能够高效处理「元素与周边元素的序关系」问题。
单调递增栈

1.2 与普通栈的区别

特性普通栈单调栈
元素顺序无约束严格单调
主要操作push/pop维护单调性
典型场景表达式求值序关系问题
时间复杂度不定均摊O(n)

1.3 核心操作模板

// 单调递增栈模板
Stack<Integer> stack = new Stack<>();
for (int num : nums) {while (!stack.isEmpty() && stack.peek() >= num) { // 破坏递增性时弹出int poped = stack.pop();// 处理弹出元素}stack.push(num); // 新元素入栈,确保栈递增
}// 单调递减栈模板
Stack<Integer> stack = new Stack<>();
for (int num : nums) {while (!stack.isEmpty() && stack.peek() <= num) { // 破坏递减性时弹出int poped = stack.pop();// 处理弹出元素}stack.push(num); // 新元素入栈,确保栈递减
}

二、单调栈核心原理

2.1 单调性维护机制

  • 入栈规则:新元素入栈前,弹出所有破坏单调性的栈顶元素
  • 元素处理:弹出元素时,当前新元素即为其「下一个更大/更小元素」
  • 均摊复杂度:每个元素最多入栈/出栈一次,总时间复杂度O(n)
    单调递减栈维护

2.2 典型应用场景

  1. 下一个更大元素:数组中每个元素右侧第一个比它大的元素
  2. 接雨水问题:计算柱状图能接的雨水总量
  3. 柱状图最大面积:求解直方图中的最大矩形面积
  4. 每日温度:计算每天需要等待多久才会升温
  5. 股票买卖问题:寻找最佳买卖时机的变种问题

三、经典案例解析

下一个更大元素

问题描述

给定数组nums,返回一个新数组,其中每个元素是原数组对应位置元素的下一个更大元素(右侧第一个比它大的元素,不存在则为-1)。

思路分析
  • 使用单调递增栈,栈中保存尚未找到下一个更大元素的元素下标
  • 遍历数组时,新元素与栈顶元素比较:
    • 若新元素更大:栈顶元素的下一个更大元素即为当前元素,弹出并记录
    • 否则:新元素下标入栈
代码实现
public int[] nextGreaterElement(int[] nums) {int[] res = new int[nums.length];Stack<Integer> stack = new Stack<>(); // 存储下标,栈中元素对应的值单调递增for (int i = nums.length - 1; i >= 0; i--) {while (!stack.isEmpty() && nums[stack.peek()] <= nums[i]) {stack.pop(); // 弹出不满足递增的元素}res[i] = stack.isEmpty() ? -1 : nums[stack.peek()];stack.push(i);}return res;
}
复杂度分析
  • 时间复杂度:O(n),每个元素入栈出栈各一次
  • 空间复杂度:O(n),栈空间最多存储n个元素

接雨水问题

问题描述

给定n个非负整数表示柱状图的高度,计算下雨后能接多少雨水。

思路分析
  • 单调栈解法:维护单调递减栈,栈中存储柱子下标
  • 当新柱子高度 >= 栈顶柱子高度时,弹出栈顶,计算中间凹槽的接水量
  • 接水量由左右边界的较小值减去中间柱子高度决定
代码实现
public int trap(int[] height) {int res = 0;Stack<Integer> stack = new Stack<>(); // 存储下标,栈中高度单调递减for (int i = 0; i < height.length; i++) {while (!stack.isEmpty() && height[i] >= height[stack.peek()]) {int mid = stack.pop();if (stack.isEmpty()) break; // 没有左边界,无法形成凹槽int left = stack.peek();int width = i - left - 1;int h = Math.min(height[left], height[i]) - height[mid];res += width * h;}stack.push(i);}return res;
}
复杂度分析
  • 时间复杂度:O(n),每个元素入栈出栈各一次
  • 空间复杂度:O(n),栈空间最多存储n个元素

柱状图最大面积

问题描述

给定直方图的高度数组,求其中最大矩形面积。

思路分析
  • 单调递增栈:栈中存储下标,对应高度单调递增
  • 每个元素出栈时,视为矩形的高,宽度由左右边界决定:
    • 左边界:栈顶元素(弹出后的新栈顶)
    • 右边界:当前元素下标
    • 宽度 = 右边界 - 左边界 - 1
代码实现
public int largestRectangleArea(int[] heights) {int res = 0;Stack<Integer> stack = new Stack<>(); // 存储下标,栈中高度单调递增int[] newHeights = Arrays.copyOf(heights, heights.length + 2); // 首尾加0,避免边界处理for (int i = 0; i < newHeights.length; i++) {while (!stack.isEmpty() && newHeights[i] < newHeights[stack.peek()]) {int h = newHeights[stack.pop()];int w = i - stack.peek() - 1;res = Math.max(res, h * w);}stack.push(i);}return res;
}
复杂度分析
  • 时间复杂度:O(n),每个元素入栈出栈各一次
  • 空间复杂度:O(n),栈空间及辅助数组

四、单调栈解题模板

4.1 通用解题步骤

  1. 确定单调性:根据问题确定使用递增栈还是递减栈(找更大元素用递增栈,找更小元素用递减栈)
  2. 定义栈存储内容:通常存储元素下标(便于计算距离),而非直接存储元素值
  3. 处理边界条件:通过虚拟边界(如首尾加0)简化边界判断
  4. 元素弹出逻辑:当新元素破坏单调性时,弹出栈顶元素并计算相关结果

4.2 常见问题映射表

问题类型单调性栈存储弹出条件结果计算方式
下一个更大元素递增栈下标新元素 > 栈顶元素新元素为栈顶元素的下一个更大元素
柱状图最大面积递增栈下标新元素 < 栈顶元素栈顶元素为高,左右边界算宽度
接雨水递减栈下标新元素 >= 栈顶元素栈顶元素为中间柱,算凹槽水量
每日温度递增栈下标新元素温度 > 栈顶温度天数为下标差

五、进阶技巧与优化

5.1 双向单调栈

对于需要同时考虑左右边界的问题(如接雨水问题),可分别使用左右单调栈计算每个位置的左右最大高度,再取较小值计算水量。虽然时间复杂度同为O(n),但代码逻辑更清晰:

// 接雨水双向栈解法
public int trap(int[] height) {int n = height.length;int[] leftMax = new int[n];int[] rightMax = new int[n];// 左单调栈(递增)Stack<Integer> leftStack = new Stack<>();for (int i = 0; i < n; i++) {while (!leftStack.isEmpty() && height[leftStack.peek()] <= height[i]) {leftStack.pop();}leftMax[i] = leftStack.isEmpty() ? 0 : height[leftStack.peek()];leftStack.push(i);}// 右单调栈(递增)Stack<Integer> rightStack = new Stack<>();for (int i = n-1; i >= 0; i--) {while (!rightStack.isEmpty() && height[rightStack.peek()] <= height[i]) {rightStack.pop();}rightMax[i] = rightStack.isEmpty() ? 0 : height[rightStack.peek()];rightStack.push(i);}int res = 0;for (int i = 0; i < n; i++) {res += (Math.min(leftMax[i], rightMax[i]) - height[i]);}return res;
}

5.2 单调栈与动态规划结合

在「股票买卖的最佳时机」系列问题中,可结合单调栈优化动态规划的状态转移,将O(n²)的暴力解法优化至O(n),我将在之后的博客中进行讲解,持续关注不错过哦。

5.3 注意事项

  • 下标与值的区分:栈中存储下标而非值,便于计算元素间的距离(如宽度、天数差)
  • 虚拟元素处理:通过在数组首尾添加虚拟元素(如0),避免单独处理边界条件
  • 单调性方向判断:明确问题需要「更大」还是「更小」元素,选择对应的单调栈类型

单调栈通过维护元素的单调性,将原本需要双重循环的序关系问题优化至线性时间,是解决「下一个更大/更小元素」类问题的核心工具。其核心思想是:用栈结构缓存尚未处理的元素,通过单调性约束快速确定元素间的序关系

That’s all, thanks for reading!
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~

http://www.dtcms.com/a/547588.html

相关文章:

  • 面料 做网站网络营销组织是什么
  • 盐山网站大连科技网站制作
  • 北海手机网站制作网站建设张家港
  • 苏州网站开发服务对接标准做好门户网站建设
  • 建造电商网站大通网站建设
  • 安全员怎么网站中做备案企业手机网站建设策划书
  • 校园二手信息网站建设wordpress爆破软件
  • 网站建设分金手指专业十成都快速建站公司
  • 汕头做网站优化公司河南app软件开发价位
  • 权威网站有哪些畜牧养殖企业网站源码
  • 资兴网站设计wordpress创建配置文件
  • 石家庄网站设计公司排名莆田做网站建设
  • 网站后台编辑器上传不了图片招远做网站价格
  • 广东网站定制一级做ae视频直播可以吗多少钱
  • 网站建设落地页河南省建设工程注册中心网站
  • 如何在vs做网站wordpress图片上传
  • 为什么要进行网站备案wordpress 内核
  • pc28网站开发深圳企业管理咨询公司排名
  • 织梦手机网站教程中国兰州网官网
  • 婚礼策划网站模板中文wordpress 文章字体大小
  • 中国十大摄影网站排名网页设计与制作全过程
  • 建设项目备案网站管理系统货源之家
  • 昆明网站建设要多少钱百度网盘电脑网页版
  • 山西省建设厅网站打不开个人做网站怎么盈利
  • 大朗做网站在cnetos 做网站服务
  • 惠州外包网站建设响应式网站建设的优势
  • 网站建设的分工软文网站外包
  • 泗洪建设局网站wordpress设置页面模板
  • 网站服务器怎么启动上海十大设计公司有哪些
  • 深圳建设银行网站建筑网校哪个比较好