【初阶解法-数据结构】包含min函数的栈(代码+图示)

【数据结构】刷题-包含min函数的栈(代码+图示)-初阶解法

文章目录

  • 【数据结构】刷题-包含min函数的栈(代码+图示)-初阶解法
    • 题目
    • 提炼题目要求
    • 分析题目
    • 总结思路
    • 代码
    • 时间/空间复杂度
    • 进阶版

题目

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的 min 函数,输入操作时保证 pop、top 和 min 函数操作时,栈中一定有元素。

此栈包含的方法有:

push(value):将value压入栈中

pop():弹出栈顶元素

top():获取栈顶元素

min():获取栈中最小元素

数据范围:操作数量满足 0≤n≤300 ,输入的元素满足 ∣val∣≤10000

栈的各个操作的时间复杂度是 O(1) ,空间复杂度是O*(n)

提炼题目要求

题目核心要求

  • 实现push(value),pop(),top(),min()函数
  • 要求各个函数的时间复杂度均为O(1)
  • 空间复杂度为O(n)

分析题目

解决这类问题的关键是设计一个能够在O(1)时间内完成 pushpoptopmin 操作的数据结构。通常,我们会考虑 使用辅助栈或其他数据结构来维护额外的信息。

当我遇到这类问题时,我会考虑以下几个步骤:

  1. 使用辅助栈:
    • 我通常会考虑使用一个辅助栈来保存额外的信息,比如最小值。
    • 辅助栈可以在主栈的每个状态下都保存一些额外的信息,以便在O(1)时间内支持 min 操作。
  2. 考虑特殊情况:
    • 考虑空栈的情况,并确保代码对空栈的处理是正确的。
  3. 保持同步:
    • 在使用辅助栈或其他数据结构时,确保主栈和辅助数据结构之间保持同步,以防止出现不一致的情况。
  4. 复杂度分析:
    • 在实现解决方案后,分析代码的时间复杂度和空间复杂度,确保它们满足问题的要求。

举例来说,如果题目要求实现一个支持O(1)时间复杂度的 min 操作的栈,我可能会考虑使用辅助栈来保存每个状态下的最小值。在 push 操作中,我会在辅助栈中更新最小值;在 pop 操作中,我会同时弹出主栈和辅助栈的栈顶元素。这样就能够保持O(1)时间复杂度的 min 操作。


总结思路

下面是一种使用辅助栈的简单实现思路初阶

  1. 主栈 s1 用于正常的栈操作。
  2. 辅助栈 s2 用于存储每个状态下的最小值。

push 操作时:

  • 将元素压入主栈 s1
  • 检查辅助栈 s2 是否为空,或者新元素是否小于等于辅助栈的栈顶元素。如果是,将新元素也压入辅助栈 s2。否则,重复压入辅助栈的栈顶元素。

pop 操作时:

  • 分别从主栈 s1 和辅助栈 s2 弹出栈顶元素。

min 操作时:

  • 直接返回辅助栈 s2 的栈顶元素。

NOTE : 这样,辅助栈 s2 中的栈顶元素始终对应于主栈 s1 的当前最小值,而且由于每次 pushpop 操作都会同时更新两个栈,保持了两个栈的同步。这样,min 操作的时间复杂度是 O(1)。

如果对于push操作中的重复压入辅助栈的栈顶元素感到困惑,我将详细解释这背后的原因。

  • 当我们仅仅在push操作中实时监控辅助栈s2的栈顶元素是否一直保持是所有元素中的最小值时,这只是解决了问题的一半。因为栈中元素的变动不仅仅是由push操作引起的,我们还需要考虑pop操作。在弹出元素的同时,主栈s1中的元素也发生了变化。因此,为了确保s2能够实时监控到pop操作,我们必须同时在主栈s1进行pop操作的时候,保证辅助栈s2也要同时更新以进行pop操作。那么问题来了,如何在s2中保证有元素可以弹出,并且不会改变栈顶元素一直是最小值呢?
    • 解决这个问题的方法是,在入栈push的时候,如果待插入的元素比最小值大,我们就将当前最小值重复入栈。这样就保证了每当主栈s1入栈一个元素时,辅助栈s2也会入栈一个元素。这种做法的好处在于,之后无论何时进行出栈pop操作,我们都能够确保s2中有元素可以弹出。而且,一旦成功弹出元素,s2的栈顶元素仍然保持是最小值!
    • 如下图演示

image-20231204215629193

(同步)正常的出栈操作

image-20231204215913351

(未同步)异常的出栈操作

image-20231204220235603

代码

import java.util.*;
import java.util.Stack;


/*
含有min函数的栈

这个题目需要我们自己实现栈的基本的结构
 */

public class Solution{

    //这个栈1是我们的主要的栈
    Stack<Integer> stack1 = new Stack<>();

//这个栈2 是我们专门用来保存最小值的栈
    Stack<Integer> stack2 = new Stack<>();

    public void push(int node) {

        //准备一个辅助栈,这个栈必须在push方法中,因为这样我们就可以直接就保证min函数里面的栈中保存的一定是最小的值
        //所以我们就只需要在插入元素的时候就进行筛查
        stack1.push(node);
       
        if(stack2.empty()||node<stack2.peek()){
            stack2.push(node);
        }else{
            stack2.push(stack2.peek());
        }
    }

    public void pop() {
        stack1.pop();
        stack2.pop();
    }

    public int top() {
        return stack1.peek();

    }

    public int min() {
        return stack2.peek();
    }
}

时间/空间复杂度


时间复杂度分析

push(int node):

  • stack1.push(node):将元素推入主栈 stack1,O(1)。
  • 判断并更新最小值:
    • 如果 stack2 为空,或者新元素 node 小于 stack2 的栈顶元素,执行 stack2.push(node),O(1)。
    • 否则,执行 stack2.push(stack2.peek()),O(1)。
  • 因此,整体的时间复杂度为 O(1)。

pop():

  • 同时从 stack1stack2 弹出栈顶元素,都是O(1)的操作。
  • 因此,整体的时间复杂度为 O(1)。

top():

  • 直接返回 stack1 的栈顶元素,O(1)的操作。
  • 因此,整体的时间复杂度为 O(1)。

min():

  • 直接返回 stack2 的栈顶元素,O(1)的操作。
  • 因此,整体的时间复杂度为 O(1)。

空间复杂度分析

  • 主栈 stack1 和辅助栈 stack2 都需要额外的空间来存储元素,因此空间复杂度是 O(n),其中 n 是推入栈的元素数量。

进阶版

进阶版 -> 使用差值:在一些情况下,我们可以使用差值来存储元素与当前状态下的最小值的关系,从而降低空间复杂度。(我会在下一篇博客里面讲的)

image-20231129200715576

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/217041.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于rocketMQ踩坑的那些事

在最近&#xff0c;我所写的这个项目需要使用到rocketMQ&#xff0c;为了图方便我便使用的是Windows版本的&#xff0c;但是在使用的过程中首先是发现无法发送消息出去&#xff0c;报错信息为 org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still …

水果店怎么做微信小程序_利用微信小程序实现业绩逆袭

标题&#xff1a;水果店如何利用微信小程序实现业绩逆袭&#xff1f; 随着移动支付的普及&#xff0c;微信小程序已经成为商业领域的一个重要工具。对于水果店来说&#xff0c;利用微信小程序可以更好地拓展业务、提高客户满意度&#xff0c;进而实现业绩逆袭。本文将为你揭示…

java连接池 理解及解释(DBCP、druid、c3p0、HikariCP)

一、在Java开发中&#xff0c;有许多常见的数据库连接池可供选择。以下是一些常见的Java数据库连接池&#xff1a;不使用数据库连接池的特性&#xff1a; 优点&#xff1a;实现简单 缺点&#xff1a;网络 IO 较多数据库的负载较高响应时间较长及 QPS 较低应用频繁的创建连接和关…

【Linux下如何生成coredump文件】

一&#xff0c;什么是coredump 我们经常听到大家说到程序core掉了&#xff0c;需要定位解决&#xff0c;这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止&#xff0c;并且在满足一定条件下&#xff08;这里为什么说需要满足一定的条件呢&#…

【离散数学】——期末刷题题库(集合)

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

成为AI产品经理——模型稳定性评估(PSI)

一、PSI作用 稳定性是指模型性能的稳定程度。 上线前需要进行模型的稳定性评估&#xff0c;是否达到上线标准。 上线后需要进行模型的稳定性的观测&#xff0c;判断模型是否需要迭代。 稳定度指标(population stability index ,PSI)。通过PSI指标&#xff0c;我们可以获得不…

学习率设置(写给自己看)

现往你的.py文件上打上以下代码&#xff1a; import torch import numpy as np from torch.optim import SGD from torch.optim import lr_scheduler from torch.nn.parameter import Parametermodel [Parameter(torch.randn(2, 2, requires_gradTrue))] optimizer SGD(mode…

12.04 二叉树中等题

513. 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 思路&#xff1a;找到最低层中最左侧的节点值&#xff0c;比较适合层序遍历&#xff0c;返回最…

【matlab】QR分解

QR分解 给定一个mn的矩阵A&#xff0c;其中m≥n&#xff0c;即矩阵A是高矩阵或者是方阵&#xff0c;QR分解将矩阵A分解为两个矩阵Q和R的乘积&#xff0c;其中矩阵Q是一个mn的各列正交的矩阵&#xff0c;即QTQI&#xff0c;矩阵R是一个nn的上三角矩阵&#xff0c;其对角线元素为…

初识动态规划算法(题目加解析)

文章目录 什么是动态规划正文力扣题第 N 个泰波那契数三步问题使用最小花费爬楼梯 总结 什么是动态规划 线性动态规划&#xff1a;是可以用一个dp表来存储内容&#xff0c;并且找到规律存储,按照规律存储。让第i个位置的值等于题目要求的答案 >dp表&#xff1a;dp表就是用一…

【数据结构】——栈|队列(基本功能)

目录 栈 基本概念 栈的常见基本操作 栈的存储 ✌栈的基本操作实现 栈的构建 栈的初始化 入栈 打印栈 出栈 获取栈顶元素 获取栈的有效元素个数 判断栈是否为空 销毁栈 队列 基本概念 队列的常见基本操作 ✌队列的基本操作实现 队列的构建 初始化 入队列 出…

不再只是android,华为自爆Harmony将对标iOS

今年10月&#xff0c;华为官方宣布&#xff0c;鸿蒙OS 4升级设备数量已突破1亿&#xff0c;成为史上升级最快的鸿蒙OS版本。 日前&#xff0c;据数码博主“定焦数码”消息&#xff0c;大厂技术员工做适配&#xff0c;通过线下沟通时&#xff0c;华为反复提到一个问题&#xff…

实战技巧:为Android应用设置独立的多语言

原文链接 实战技巧&#xff1a;为Android应用设置独立的多语言 通常情况下多语言的设置都在系统设置中&#xff0c;应用需要做的就是提供本应用所使用的字串的多语言翻译&#xff0c;使用时使用R.string.app_name类似的引用&#xff0c;然后系统会根据用户在系统设置中的选项来…

不瞒各位,不安装软件也能操作Xmind文档

大家好&#xff0c;我是小悟 作为搞技术的一个人群&#xff0c;时不时就要接收产品经理发过来的思维脑图&#xff0c;而此类文档往往是以Xmind编写的&#xff0c;如果你的电脑里面没有安装Xmind的话&#xff0c;不好意思&#xff0c;是打不开这类后缀结尾的文档。 打不开的话…

【雷电模拟器桥接问题解决方法】

1.ROOT权限开启 2.开启网络桥接模式&#xff0c;选择静态IP设置&#xff0c;点击安装桥接网卡&#xff0c;填写IP地址&#xff08;注意&#xff1a;IP地址要与host主机在同一IP段内&#xff09; 3.重启后 adb shell就能进入到模拟器控制台中了&#xff0c;如果出现以下内容&…

进程程序替换和shell实现

先前fork说创建子进程执行代码&#xff0c;如何让子进程执行和父进程完全不一样的代码?程序替换。 一 单进程替换演示 1 execl函数使用 最近转到在vs code下写代码&#xff0c;之前也在xhell下用过execl函数&#xff0c;所以才想写篇博客总结总结&#xff0c;没想到在vs code…

(C语言)计算n的阶乘

要求使用双精度 #include<stdio.h> double factorial(int n) {if(n 1)return 1;return n * factorial(n-1); } int main() {int n ;double res;scanf("%d",&n);res factorial(n);printf("%lf",res); return 0; } 运行截图&#xff1a; 注&am…

oops-framework框架 之 界面管理(三)

引擎&#xff1a; CocosCreator 3.8.0 环境&#xff1a; Mac Gitee: oops-game-kit 注&#xff1a; 作者dgflash的oops-framework框架QQ群&#xff1a; 628575875 回顾 在上文中主要通过oops-game-kit大家了一个新的模版项目&#xff0c; 主要注意项是resources目录下的两个文…

Python Opencv实践 - Yolov3目标检测

本文使用CPU来做运算&#xff0c;未使用GPU。练习项目&#xff0c;参考了网上部分资料。 如果要用TensorFlow做检测&#xff0c;可以参考这里 使用GPU运行基于pytorch的yolov3代码的准备工作_little han的博客-CSDN博客文章浏览阅读943次。记录一下自己刚拿到带独显的电脑&a…

卷积神经网络(CNN):艺术作品识别

文章目录 一、前言一、设置GPU二、导入数据1. 导入数据2. 检查数据3. 配置数据集4. 数据可视化 三、构建模型四、编译五、训练模型六、评估模型1. Accuracy与Loss图2. 混淆矩阵3. 各项指标评估 一、前言 我的环境&#xff1a; 语言环境&#xff1a;Python3.6.5编译器&#xf…