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

2025.11.10 力扣每日一题

3542.将所有元素变为0的最少操作次数

class Solution {
public:int minOperations(vector<int>& nums) {vector<int> s;int res = 0;for(int a : nums){while(!s.empty() && s.back() > a){s.pop_back();}if( a==0) continue;if(s.empty() || s.back() < a){++res;s.push_back(a);}}return res;}
};

单线栈知识点:

单调栈是一种特殊的栈数据结构,其核心特性是:栈内的元素始终保持单调递增单调递减的顺序。这种特性使得它在解决 “找下一个更大 / 更小元素”“区间最值” 等问题时效率极高(时间复杂度通常为 O (n))。

核心概念

  • 单调性:栈内元素从栈底到栈顶严格遵循递增(或递减)规则。
  • 操作原则:当新元素入栈时,若破坏单调性,则弹出栈顶元素,直到栈满足单调性后再入栈。
  • 用途:高效寻找数组中每个元素的 “下一个更大元素”“上一个更小元素” 等,避免暴力遍历(O (n²))。

分类

  1. 单调递增栈:栈内元素从栈底到栈顶从小到大排列。例如:[1, 3, 5, 7]

  2. 单调递减栈:栈内元素从栈底到栈顶从大到小排列。例如:[7, 5, 3, 1]

工作流程(以单调递增栈为例)

假设数组为 [2, 1, 3],模拟入栈过程:

  1. 元素 2 入栈,栈为 [2](满足递增)。
  2. 新元素 1 比栈顶 2 小,破坏递增性,弹出 2,栈为空后入栈 1,栈为 [1]
  3. 新元素 3 比栈顶 1 大,直接入栈,栈为 [1, 3](满足递增)。

最终栈保持递增,且过程中通过弹出元素可记录 “被弹出元素的下一个更大元素是当前新元素”(如 2 的下一个更大元素是 3)。

典型应用

  1. 下一个更大元素问题:对数组中每个元素,找到右侧第一个比它大的元素,若不存在则为 -1。示例:nums = [2, 1, 2, 4, 3]答案:[4, 2, 4, -1, -1]解法:用单调递减栈,遍历数组时,弹出栈顶元素并记录当前元素为其 “下一个更大元素”。

  2. 接雨水问题:计算数组中 “凹槽” 能接住的雨水量(如 [0,1,0,2,1,0,1,3,2,1,2,1] 答案为 6)。解法:用单调递减栈,栈内存储 “凹槽左边界”,遇到更高元素时计算凹槽面积。

  3. 柱状图中最大的矩形问题:找到柱状图中能容纳的最大矩形面积(如 [2,1,5,6,2,3] 答案为 10)。解法:用单调递增栈,栈内存储柱子索引,遇到更矮柱子时弹出并计算以弹出柱子为高的最大矩形。

优势

  • 时间效率:每个元素最多入栈和出栈一次,总时间复杂度为 O (n)。
  • 简洁性:通过栈的单调性,可在遍历过程中同步记录所需信息,避免嵌套循环。

总结

单调栈的核心是利用 “栈的单调性” 过滤无效元素,只保留对后续计算有价值的元素,从而高效解决各类区间相关问题。掌握它的关键是理解 “何时入栈、何时出栈” 以及 “弹出元素时能获取哪些信息”。

代码应用:

这段代码是用来解决 “将所有元素变为 0 的最少操作次数” 问题的,其核心思路是利用单调递增栈来统计需要的最少操作次数,与题目中 “每次操作可选择一个连续子数组,将其中最小的非负整数设为 0” 的规则相契合。

代码逐行解释

  1. vector<int> s;定义一个单调递增栈,栈中存储的是 “当前需要处理的最小非负整数的递增序列”。

  2. int res = 0;用于记录最少操作次数。

  3. for(int a : nums)遍历数组中的每个元素。

  4. while(!s.empty() && s.back() > a)这是单调栈的核心操作:

    • 当栈不为空,且 ** 栈顶元素大于当前元素a** 时,弹出栈顶元素。
    • 目的是维护栈的单调递增性,确保栈中只保留 “当前未被覆盖的最小非负整数”。
  5. if( a==0) continue;如果当前元素是 0,无需处理(因为目标就是将所有元素变为 0,0 本身已经满足),直接跳过。

  6. if(s.empty() || s.back() < a)当栈为空,或 ** 栈顶元素小于当前元素a** 时:

    • ++res;:操作次数加 1(因为需要对当前元素a执行一次新的操作)。
    • s.push_back(a);:将当前元素a入栈,维护单调递增性。

逻辑本质

代码的核心是按 “最小非负整数的递增顺序” 统计操作次数

  • 每次遇到一个新的 “未被更小元素覆盖的非 0 元素” 时,就需要一次操作来将其变为 0。
  • 单调栈确保了 “只有比栈中所有元素更大的非 0 元素” 才会触发新的操作,从而保证操作次数最少。

示例验证(以nums = [1,2,1,2,1,2]为例)

遍历过程:

  • a=1:栈空,res=1,栈变为[1]
  • a=2:栈顶1 < 2res=2,栈变为[1,2]
  • a=1:栈顶2 > 1,弹出2;栈顶1 == 1,不满足stack.back() < a,不操作,栈仍为[1]
  • a=2:栈顶1 < 2res=3,栈变为[1,2]
  • a=1:栈顶2 > 1,弹出2;栈顶1 == 1,不操作,栈仍为[1]
  • a=2:栈顶1 < 2res=4,栈变为[1,2]

最终res=4,与预期结果一致。

总结

这段代码通过单调递增栈巧妙地维护了 “最小非负整数的递增序列”,确保每次操作都针对 “当前未被覆盖的最小非 0 元素”,从而得到最少操作次数,时间复杂度为O(n)(每个元素最多入栈和出栈一次)。

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

相关文章:

  • 麻城网站开发同一网站相同form id
  • dede网站制作wordpress长微博工具
  • 专业定制铸铁T型槽地轨,提供稳定的制造、实验基准线
  • PyCharm如何像其他idea软件跨行选择文本
  • 【场景题】线上接口响应慢,应该如何排查问题?
  • Product Hunt 每日热榜 | 2025-11-10
  • 【智能体(Agent)技术深度解析】从架构到实现细节,核心是实现“感知环境→处理信息→决策行动→影响环境”的闭环
  • 网站的登陆注册页面怎么做做水果网站弄个什么名字
  • Advisor与@Aspect
  • Java基础——集合进阶6
  • 网站建设湛江分类信息网站如何做排名
  • 二十七、通信接口
  • 个人网站备案条件个人怎么做网页
  • SQL 相关子查询:性能杀手及其优化方法
  • 一文掌握UI自动化测试
  • 金融保险银行营销AI数字化转型培训讲师培训老师唐兴通讲金融银保团队险年金险市场销售
  • 质效飞跃,优测金融数智质效解决方案全新升级!
  • 智网案例精选|光联云网融合智驱,重塑金融数字化转型新格局
  • 自适应网站建设极速建站WordPress更新emoji
  • watch监视-ref对象类型数据
  • 网站建设的英语怎么做淘宝客网站做淘客
  • MBSE:数字模型重塑系统工程未来
  • 排序算法的相关讨论
  • HDFS 之 CacheAdmin
  • MySQL数据库07:分组查询与分类查询
  • 淄博网站公司高端网站建设公司怎么做推广
  • MCU的I/O防护
  • 碳纤维便携式气象站:轻量化设计,随时随地掌握气象数据
  • 华为-AI智算网络学习-2
  • K8S RD: Kubernetes从核心调度到故障排查、网络优化与日志收集指南