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

数据结构栈的经典OJ题【leetcode最小栈问题大剖析】【leetcode有效的括号问题大剖析】

目录

0.前言

1.最小栈

1.1 原题展示

1.2 思路分析

1.2.1 场景引入

1.2.2 思路

1.3 代码实现

1.3.1 最小栈的删除

1.3.2 最小栈的插入

1.3.3 获取栈顶元素

1.3.4 获取当前栈的最小值

2. 有效的括号


0.前言

本篇博客已经把两个关于栈的OJ题分块,可以根据目录跳转,并且代码已经上传至gitee可自取。

1.最小栈

155. 最小栈 - 力扣(LeetCode)

1.1 原题展示

本题需要我们设计一个栈,这个栈相对于普通的栈,有一个特异功能,可以在常数O(1)的时间复杂度下直接找到并返回,现在栈内所有元素的最小值是多少。

这个要设计的有特异功能的栈,我们称之为最小栈,本题就是要实现一个MinStack类。多了一个特异接口getMin。

1.2 思路分析

1.2.1 场景引入

我们如何实时记录当前栈的最小值呢?有人说,我们可以在MinStack类当中记录一个int _min成员,每次插入之后,我们对比一下这个_min,如果插入的数据比当前的_min更小的话,那就更新_min,这样不就可以实时记录当前最小值吗?

class MinStack {
private:stack<int> _st;int _min;
};

但是这样并不能的哦,如果你删除数据呢?如果你删除一个当前的_min值元素,那你能知道,现在删除完_min元素之后,栈的新最小值_min是什么,需要更新什么值呢?这就不知道了吧!!!

所以我们的思路是再存一个存放最小值的容器,这个容器负责存储如果每次删除完_min最小值之后,可以从这个容器当中再找到次小的_min的值

从时序角度上来说,一个栈的最小值,肯定是一浪更比一浪强,前浪被拍在沙滩上。在插入数据的过程中,一个栈内数据的最小值不断的被更新成越来越小的。相反,在删除数据的过程中,如果我们删除了现在的最小值(后浪),我们应该把曾经作为最小值的值(被拍死的前浪),作为新的最小值。

栈这个容器,是后进先出,先进后出,我们的记录的最小值:先被作为最小值(被拍死的前浪们)的元素是后出的最新一次作为最小值的元素,肯定是优先被删除的,后成为最小值的值要先出。所以我们选取栈作为记录每次最小值的容器。

class MinStack {
private:stack<int> _st;stack<int> _min_st;

1.2.2 思路

所以我们除了定义一个主栈_st存储所有插入的数据,还要定义一个最小栈_min_st,用来存储每次当前栈的最小值,始终维持这个最小栈的栈顶元素始终代表当前的最小值

如果我们在主栈当中插入一个比当前栈最小值_min,还要更小的一个数据more min,那么我们就在最小栈当中插入以记录这个更小的一个数据。而如果是一个插入更大的数据,那就没有必要动最小栈_min_st,此时最小值不变。

如果我们在主栈当中删除了当前栈的最小值,那么我们也要在最小栈进行出栈操作去除更新当前的最小值,出栈之后,那接下来最小栈的栈顶,就变成了次小的最小值,此时最小栈的栈顶仍然代表着当前栈的最小值!

1.3 代码实现

1.3.1 最小栈的删除

最小栈的栈顶数据代表当前栈内所有数据的最小值,如果删除的是当前最小值,那要顺便再对最小栈出栈,更新为次小值为最小值!

void pop() {//我们删除还要看删除的是否在现在的最小栈中int val = _st.top();if(val == _min_st.top()) //是最小栈的该元素,要删除{_st.pop();_min_st.pop();}else //不是最小栈中的元素,就可以直接出栈,然后现在min_st中的顶还是最小值{_st.pop();}}

1.3.2 最小栈的插入

插入比当前最小值更小的数据,更新入栈_min_st,或者还有一种特殊情况,如果是一个空栈,我们也要更新入栈_min_st!

如果插入比当前最小值还大的数据,那么我们就没有必要动最小栈_min_st。

而如果插入的是和当前最小值相等的数据,那么我们入不入最小栈呢?不管入不入栈,都不会影响当前栈的最小值的记录,这样看入不入的确没有太大关系。可是你想一想,如果你遇到相等最小值的时候,不入最小栈的话,在删除逻辑中,如果你删除了这个最小值,那么我们如果出栈_min_st,那此时最小栈的栈顶元素就不能代表当前栈内元素的最小值了

例如,你依次插入了 2 3 4 1 1,那最小栈从栈底到栈顶就依次是2 1,如果我要删除1,那主栈内就变为2 3 4 1,那我最小栈就会变成2,此时最小栈栈顶就不是当前栈的最小值。

所以如果插入的是和当前最小值相等的数据,也要入最小栈。

void push(int val) {_st.push(val);if(_min_st.empty()){_min_st.push(val);}else //不是空{//如果出现了更小的val,那就入栈if(val<=_min_st.top()) //相等的情况也必须入栈,不然我们删除的时候就不知道最小值在栈底还有多个的情况{_min_st.push(val);}//否则更大的val就不用入栈了}}

1.3.3 获取栈顶元素

返回主栈的栈顶。

int top() {return _st.top();}

1.3.4 获取当前栈的最小值

返回最小栈的栈顶。

int getMin() {return _min_st.top();}

2. 有效的括号

20. 有效的括号 - 力扣(LeetCode)

 就是给你一个括号序列,看看这个是否是一个有效的括号序列。那么什么是有效的括号呢?其实就是最近的一个左括号和离得它最近的右括号能够相互匹配,也可以说是一个右括号和离得它最近的左括号能够相互匹配(匹配的意思是 "(" 只能去匹配 ")" ,"{" 只能去匹配 "}" ,"[" 只能去匹配 "]" )

这里用栈结构即可很好的解决,如果遇到了左括号,那么就入栈,等待最近一个右括号的匹配(先进后出,后进先出,一定是后面的左括号先被匹配,前面的括号后被匹配,这完美的符合栈的性质),如果遇到了右括号,那么我们就出栈顶数据,即找到最近的一个左括号,进行匹配检查,如果不匹配,那就return false,如果匹配就继续检查。

转换成代码就是这样的:

bool isValid(char * s){此时就可以利用栈先进后出的特性进行判断*///遍历遇到左括号,则入栈//遍历遇到右括号,则出栈数据对右括号进行匹配//到最后遍历匹配完毕,栈为空即可【这是针对左括号多出来的情况】//【而右括号多出来的情况,则是栈中没有数据与之匹配了,此时也不是有效的括号false】//定义一个栈Stack st;StackInit(&st);//遍历字符串括号集while(*s!='\0'){//遇到左括号if(*s == '{' || *s == '[' || *s=='('){StackPush(&st,*s);}else{//遇到右括号//判断非法情况,右括号多余左括号if(StackEmpty(&st)){return false;}//出栈和右括号进行匹配int left_brace = StackTop(&st);StackPop(&st);//不匹配则false,匹配则继续遍历比较if(left_brace=='{'&&*s != '}'|| left_brace=='['&&*s != ']'|| left_brace=='('&&*s != ')'){return false;}}++s;}//判断非法情况,左括号多余右括号return StackEmpty(&st);
}

当然我们还需要想一想左右括号如果数量不匹配的情况:到最后遍历匹配完毕,如果栈为空那就是左右括号全部被匹配成功,而如果栈不为空,这是针对左括号数量多于右括号的情况;而右括号多出来的情况,则是栈中没有数据与之匹配了,此时也不是有效的括号false。

相关文章:

数据结构栈的经典OJ题【leetcode最小栈问题大剖析】【leetcode有效的括号问题大剖析】

目录 0.前言 1.最小栈 1.1 原题展示 1.2 思路分析 1.2.1 场景引入 1.2.2 思路 1.3 代码实现 1.3.1 最小栈的删除 1.3.2 最小栈的插入 1.3.3 获取栈顶元素 1.3.4 获取当前栈的最小值 2. 有效的括号 0.前言 本篇博客已经把两个关于栈的OJ题分块&#xff0c;可以根据目…...

数据结构与算法之打家劫舍(一)动态规划思想

动态规划里面一部题目打家劫舍是一类经典的算法题目之一&#xff0c;他有各种各样的变式&#xff0c;这一篇文章和大家分享一下打家劫舍最基础的一道题目&#xff0c;掌握这一道题目&#xff0c;为下一道题目打下基础。我们直接进入正题。一.题目大家如果刚接触这样的题目&…...

无人驾驶路径规划论文简要

A Review of Motion Planning Techniques for Automated Vehicles综述和分类0Motion Planning for Autonomous Driving with a Conformal Spatiotemporal Lattice从unstructured环境向structured环境的拓展&#xff0c;同时还从state lattice拓展到了spatiotemporal lattice从而…...

C++ sort()函数和priority_queue容器中比较函数的区别

普通的queue是一种先进先出的数据结构&#xff0c;元素在队列尾追加&#xff0c;而从队列头删除。priority_queue中元素被赋予优先级。在创建的时候根据优先级进行了按照从大到小或者从小到大进行了自动排列&#xff08;大顶堆or小顶堆&#xff09;。可以以O(log n) 的效率查找…...

STM32开发(14)----CubeMX配置ADC

CubeMX配置ADC前言一、什么是ADC&#xff1f;二、实验过程1.单通道ADC采集STM32CubeMX配置代码实现2.多通道ADC采样(非DMA)STM32CubeMX配置代码实现3.多通道ADC采样&#xff08;DMA&#xff09;STM32CubeMX配置代码实现总结前言 本章介绍使用STM32CubeMX对ADC进行配置的方法&a…...

Simple RNN、LSTM、GRU序列模型原理

一。循环神经网络RNN 用于处理序列数据的神经网络就叫循环神经网络。序列数据说直白点就是随时间变化的数据&#xff0c;循环神经网络它能够根据这种数据推出下文结果。RNN是通过嵌含前一时刻的状态信息实行训练的。 RNN神经网络有3个变种&#xff0c;分别为Simple RNN、LSTM、…...

【原创】java+swing+mysql生肖星座查询系统设计与实现

今天我们来开发一个比较有趣的系统&#xff0c;根据生日查询生肖星座&#xff0c;输入生日&#xff0c;系统根据这个日期自动计算出生肖和星座信息反馈到界面。我们还是使用javaswingmysql去实现这样的一个系统。 功能分析&#xff1a; 生肖星座查询系统&#xff0c;顾名思义…...

CentOS 环境 OpneSIPS 3.1 版本安装及使用

文章目录1. OpenSIPS 源码下载2. 工具准备3. 编译安装4. opensips-cli 工具安装5. 启动 OpenSIPS 实例1. OpenSIPS 源码下载 使用以下命令即可下载 OpenSIPS 的源码&#xff0c;笔者下载的是比较稳定的 3.1 版本&#xff0c;读者有兴趣也可前往 官方传送门 sudo git clone htt…...

SQL95 从 Products 表中检索所有的产品名称以及对应的销售总数

描述 Products 表中检索所有的产品名称&#xff1a;prod_name、产品id&#xff1a;prod_idprod_idprod_namea0001egga0002socketsa0013coffeea0003colaOrderItems代表订单商品表&#xff0c;订单产品&#xff1a;prod_id、售出数量&#xff1a;quantityprod_idquantitya0001105…...

平时技术积累很少,面试时又会问很多这个难题怎么破?别慌,没事看看这份Java面试指南,解决你的小烦恼!

前言技术面试是每个程序员都需要去经历的事情&#xff0c;随着行业的发展&#xff0c;新技术的不断迭代&#xff0c;技术面试的难度也越来越高&#xff0c;但是对于大多数程序员来说&#xff0c;工作的主要内容只是去实现各种业务逻辑&#xff0c;涉及的技术难度并不高&#xf…...

SQL Server 数据库的备份

为何要备份数据库&#xff1f; 备份 SQL Server 数据库、在备份上运行测试还原过程以及在另一个安全位置存储备份副本可防止可能的灾难性数据丢失。 备份是保护数据的唯一方法 。 使用有效的数据库备份&#xff0c;可从多种故障中恢复数据&#xff0c;例如&#xff1a; 介质…...

NCNN Conv量化详解1

1. NCNN的Conv量化计算流程 正常的fp32计算中,一个Conv的计算流程如下: 在NCNN Conv进行Int8计算时,计算流程如下: NCNN首先将输入(bottom_blob)和权重(weight_blob)量化成INT8,在INT8下计算卷积,然后反量化到fp32,再和未量化的bias相加,得到输出(top_blob) 输入和…...

Redis大key多key拆分方案

业务场景中经常会有各种大key多key的情况&#xff0c; 比如&#xff1a;1&#xff1a;单个简单的key存储的value很大2&#xff1a;hash&#xff0c; set&#xff0c;zset&#xff0c;list 中存储过多的元素&#xff08;以万为单位&#xff09;3&#xff1a;一个集群存储了上亿的…...

python的类如何使用?兔c同学一篇关于python类的博文概述

本章内容如目录 所示&#xff1a; 文章目录1. 创建和使用类1.1 创建第一个python 类1.2 版本差异1.3 根据类创建实例1. 访问属性2. 调用方法3. 创建多个实例2. 使用类和实例2.1 给属性指定默认值2.2 修改属性的值3. 继承3.1 子类的 __init __()3.2 给子类定义属性和方法3.3 重写…...

Day60 动态规划总结

647. 回文子串 回文的做法注定我们得从里面入手&#xff0c;逐渐扩散到边界 初始化&#xff1a;准备一个ans&#xff0c;找到一个回文子串加一个 dp [[0] * n for _ in range(n)]ans 0 遍历公式&#xff1a; 当s[i]s[j]的时候&#xff0c;只要里面还是回文串&#xff0c;就能…...

UVM仿真环境搭建

环境 本实验使用环境为&#xff1a; Win10平台下的Modelsim SE-64 2019.2 代码 dut代码&#xff1a; module dut(clk,rst_n, rxd,rx_dv,txd,tx_en); input clk; input rst_n; input[7:0] rxd; input rx_dv; output [7:0] txd; output tx_en;reg[7:0] txd; reg tx_en;always…...

Azure AI基础到实战(C#2022)-认知服务(1)

目录 Azure 认知服务概述计算机视觉概述数据隐私和安全性计算机视觉快速入门光学字符识别 (OCR)OCR APIOCR 常用功能Azure 门户准备两种部署方式OCR项目实战之车牌识别Azure 认知服务概述 Azure 认知服务是基于云的人工智能 (AI) 服务,可帮助开发人员在不具备直接的 AI 或数据…...

光栅化Triangles(笔记)

field of view (可见区域) 该角度越大,需要透视投影的角度越大,成像显示的内容越多 有Y值,则可得出成像范围 屏幕: 典型的光栅处理设备所有像素都被表示为x,y坐标轴形式 3D方块成像步骤: 先将其所在平面化为 与屏幕等长等宽的形式: 如何将一个三角形拆成像素&#xff1f;采样…...

【Oarcle】如何显示日本年号的日期格式 ?

语句大于一切&#xff0c;还需要语言吗&#xff1f; 1. SELECT TO_CHAR(SYSDATE,EEYY/MM/DD,NLS_CALENDAR JAPANESE IMPERIAL) from dual;结果是&#xff1a; 令和05/02/25 Oracle SQL文中&#xff0c;年月日的显示&#xff0c;一定要使用双引号括起来&#xff0c;如 select…...

57_Pandas中的json_normalize将字典列表转换为DataFrame

57_Pandas中的json_normalize将字典列表转换为DataFrame 可以使用 pandas.json_normalize() 将具有公共键的字典列表转换为 pandas.DataFrame。 由于它是一种常用的JSON格式&#xff0c;可以通过Web API获取&#xff0c;所以能够将其转换为pandas.DataFrame是非常方便的。 在…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...