热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LeetCode算法挑战:最小栈的Java实现与优化

这是悦乐书的第177次更新,第179篇原创

01 看题和准备

今天介绍的是LeetCode算法题中Easy级别的第36题(顺位题号是155)。设计一个支持push,pop,top和在恒定时间内检索最小元素的堆栈。

push(x) - 将元素x推入堆栈。

pop() - 删除堆栈顶部的元素。

top() - 获取顶部元素。

getMin() - 检索堆栈中的最小元素。

例如:

MinStack minStack = new MinStack();

minStack.push(-2);

minStack.push(0);

minStack.push(-3);

minStack.getMin(); - >返回-3。

minStack.pop();

minStack.top(); - >返回0。

minStack.getMin(); - >返回-2。

本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。

02 第一种解法

利用整型数组和ArrayList作为栈。

入栈的时候,创建一个容量为2的数组,数组第一个元素是要入栈的元素,第二个元素是最小值,将数组添加到list中。

出栈的时候,获取list的最后一个元素,并将其移除,此时的最小值是list最后一位元素(数组)的第二个值。

获取栈顶,即是list中最后一位元素(数组)的第一个值。

最小值直接返回最小值即可。

class MinStack {

    private List stack ;
    private int min ;

    public MinStack() {
        stack = new ArrayList();
    }

    public void push(int x) {
        int[] arr = new int[2];
        arr[0] = x;
        arr[1] = stack.isEmpty() ? x : Math.min(x, min);
        min = arr[1];
        stack.add(arr);
    }

    public void pop() {
        if (!stack.isEmpty()) {
            stack.remove(stack.size()-1);
            min = stack.isEmpty() ? 0 : stack.get(stack.size()-1)[1];
        }
    }

    public int top() {
        return stack.get(stack.size()-1)[0];
    }

    public int getMin() {
        return min;
    }
}

03 第二种解法

此解法使用了栈本身和优先队列两种结构,优先队列是为了解决最小值的问题。

入栈、出栈、栈顶这些操作都可以用栈本身的方法,而最小值则是优先队列的头部元素,因为优先队列自带排序算法,在初始化时如果不指定排序方式,则默认以自然方式排序。所以在入栈时,一并也将元素放入优先队列中,而最小值就是队列的头部元素,而其他元素的顺序是不是按升序依次排列的,这个还真不一定,但是如果你通过实现Comparable接口,重写其compareTo方法,可以按照自己定义的方式来排序。

class MinStack2 {
    PriorityQueue pQueue = new PriorityQueue(); 
    Stack stack = new Stack();                    

    public MinStack2() {}

    public void push(int x) {
        pQueue.add(x);
        stack.push(x);
    }

    public void pop() {
        int trmp = stack.pop();
        pQueue.remove(trmp);
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return pQueue.peek();
    }
}

04 第三种解法

使用两个栈,一个作为正常的栈进行入栈、出栈、获取栈顶操作,另外一个栈则存储最小值,每次在第一个栈进行入栈和出栈操作时,都要进行判断,对第二个栈中的最小值进行相应的操作。

class MinStack3 {
    private Stack s1 = new Stack<>();
    private Stack s2 = new Stack<>();

    public MinStack3() {}

    public void push(int x) {
        s1.push(x);
        if (s2.isEmpty() || s2.peek() >= x) {
            s2.push(x);
        }
    }

    public void pop() {
        int x = s1.pop();
        if (s2.peek() == x) s2.pop();
    }

    public int top() {
        return s1.peek();
    }

    public int getMin() {
        return s2.peek();
    }
}

05 第四种解法

较之第三种解法,此解法只使用了一个栈来完成入栈、出栈、获取栈顶和最小值的全部操作。

入栈时,如果新入栈的元素比最小值小,那么要将旧的最小值入栈,并且新的最小值是此时新入栈的元素,最后再将新元素入栈。

出栈时,如果要移除的元素正好是当前最小值,那么就需要再出栈一次,并且最小值等于第二次出栈要移除的值,因为入栈时是会将旧的最小值添加进去的,所以出栈时要做此判断。

class MinStack4 {
    int min = Integer.MAX_VALUE;
    Stack stack = new Stack();

    public void push(int x) {
        if(x <= min){          
            stack.push(min);
            min = x;
        }
        stack.push(x);
    }

    public void pop() {
        if(stack.pop() == min) {
            min=stack.pop();
        }
    }

    public int top() {
        return stack.peek();
    }

    public int getMin() {
        return min;
    }
}

06 小结

算法专题目前已连续日更超过一个月,算法题文章35+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!


推荐阅读
  • 本章深入探讨了Java中的多态特性,这是面向对象编程的核心概念之一。多态指的是同一操作作用于不同的对象时,可以有不同的解释和执行方式。在Java中,多态通过父类引用变量引用子类对象来实现,即 `父类类型 引用变量名 = new 子类类型();`。这种方式允许程序在运行时根据实际对象的类型动态地选择合适的方法执行,从而提高代码的灵活性和可扩展性。此外,本章还详细介绍了多态的应用场景和注意事项,帮助读者更好地理解和运用这一重要概念。 ... [详细]
  • 问题背景:在使用Struts2注解实现ZIP文件下载功能时,由于InputStream未正确关闭,导致Tomcat服务器异常终止。重启后,系统抛出`java.io.EOFException`错误。具体表现为,在文件下载过程中,如果请求未正常完成或客户端提前中断连接,未关闭的InputStream会占用资源,最终导致服务器资源耗尽,触发异常。为解决此问题,建议在代码中确保InputStream在使用完毕后能够及时且正确地关闭,以避免资源泄露和服务器崩溃。 ... [详细]
  • 字符串对比竟也暗藏玄机,你是否认同?
    在探讨字符串对比技术时,本文通过两个具体案例深入剖析了其背后的复杂性与技巧。首先,案例一部分详细介绍了需求背景、分析过程及两种不同的代码实现方法,并进行了总结。接着,案例二同样从需求描述出发,逐步解析问题并提供解决方案,旨在揭示字符串处理中容易被忽视的关键细节和技术挑战。 ... [详细]
  • 算术表达式分析与解析技术初探
    本文初步探讨了算术表达式的分析与解析技术,针对作者在职业转型过程中发现自身算法基础薄弱的问题,决定在接下来的三个月内,系统地学习和掌握常用数据结构与算法,以提升个人技术能力。研究内容不仅涵盖了基本的算术表达式解析方法,还深入讨论了其在实际应用中的优化策略,为相关领域的进一步研究奠定了基础。 ... [详细]
  • 程序连接MySQL数据库的多种方法详解 ... [详细]
  • Android数组截取技巧及JNI数组交互在仓库构建中的应用分析
    在Android开发中,数组截取技巧和JNI数组交互在仓库构建中的应用具有重要意义。JNI提供了两种主要的数组处理方法:一是生成原生层数组的副本,二是直接通过数组指针进行操作。在进行字符串处理时,如果需要执行其他复杂操作,可以结合这两种方法以提高效率和灵活性。此外,合理利用这些技术可以显著提升应用程序的性能和稳定性。 ... [详细]
  • 在Java NIO中,`ByteBuffer` 的内存分配方式分为 `allocate` 和 `allocateDirect`。前者在JVM堆内存中分配空间,返回 `HeapByteBuffer` 实例,初始位置为0,容量和限制由参数指定。而 `allocateDirect` 则在操作系统本地内存中分配,返回 `DirectByteBuffer`,适用于需要频繁与I/O操作交互的场景,性能更高但管理成本较大。两者在内存管理和性能上各有优劣,选择时需根据具体应用场景权衡。 ... [详细]
  • 将 Eclipse 中的 Java Web 项目迁移至 IntelliJ IDEA 并配置 Tomcat 环境
    为了适应更高效的工作流程,本文详细介绍了如何将基于Eclipse构建的Java Web项目迁移到IntelliJ IDEA,并在新环境中配置Tomcat服务器,以确保项目的顺利运行。此过程不仅涉及项目文件的转移,还包括解决可能遇到的兼容性问题和环境配置挑战。通过本文的指导,开发者可以轻松实现从Eclipse到IntelliJ IDEA的过渡,提升开发效率。 ... [详细]
  • 在Java中准确获取字符串长度的方法与技巧解析。首先,通过Eclipse创建一个新的Java项目,项目名称可自定义。完成后,右键点击项目名称,选择新建类。在类中,可以通过调用`String`对象的`length()`方法来统计字符串的长度。此外,还可以利用其他字符串处理库或工具类来实现更复杂的字符串长度计算,例如使用Apache Commons Lang库中的`StringUtils`类,以提高代码的可读性和健壮性。 ... [详细]
  • 通过Apache Commons FileUpload组件,可以根据具体应用需求实现多样化的文件上传功能。在基本应用场景中,开发者可以通过调用单一方法来解析Servlet请求,从而轻松处理文件上传任务。此外,该组件还提供了丰富的配置选项和高级功能,支持大文件上传、多文件并发处理等复杂场景,显著提升了文件上传的效率和可靠性。 ... [详细]
  • 基于灰度直方图的水果识别系统开发:MATLAB源代码及图形用户界面设计
    基于灰度直方图的水果识别系统开发:MATLAB源代码及图形用户界面设计 ... [详细]
  • 题目1:给定一个非空数组A,包含有N个整数,起始下标为0。数组包含有奇数个元素,其中除了唯一一个元素之外,其他 ... [详细]
  • 一.问题汇总:折线图问题与解决折线图中的多条折线,怎么设置?怎么设置echarts的背景颜色?怎么设置X轴,Y ... [详细]
  • 深入解析 org.hibernate.event.spi.EventSource.getFactory() 方法及其应用实例 ... [详细]
  • 在Eclipse环境中部署Spring框架源码的过程中,本文详细探讨了Junit加载ApplicationContext的具体实现方法。通过使用`ClassPathXmlApplicationContext`类,可以有效地初始化Spring容器,从而便于单元测试的执行。此外,文章还深入分析了Spring框架的核心机制,包括依赖注入和AOP等方面的原理,为开发者提供了宝贵的实战经验和技术指导。 ... [详细]
author-avatar
不完整的记忆721_560
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有