LeetCode算法题-Min Stack(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<int[]> stack ;
    private int min ;

    public MinStack() {
        stack = new ArrayList<int[]>();
    }

    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<Integer> pQueue = new PriorityQueue<Integer>();
    Stack<Integer> stack = new Stack<Integer>();                    

    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<Integer> s1 = new Stack<>();
    private Stack<Integer> 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<Integer> stack = new Stack<Integer>();

    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+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。

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

原文地址:https://www.cnblogs.com/xiaochuan94/p/9986908.html

时间: 2024-09-30 22:55:37

LeetCode算法题-Min Stack(Java实现)的相关文章

LeetCode算法题-Sqrt(Java实现)

这是悦乐书的第158次更新,第160篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第17题(顺位题号是69). 计算并返回x的平方根,其中x保证为非负整数. 由于返回类型是整数,因此将截断十进制数字,并仅返回结果的整数部分.例如: 输入:4 输出:2 输入:8 输出:2 说明:8的平方根是2.82842 ...,从2以后小数部分被截断,返回2 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试.

LeetCode Algorithms Questions List (LeetCode 算法题列表)- Java Solutions

因为在开始写这个博客之前,已经刷了100题了,所以现在还是有很多题目没有加进来,为了方便查找哪些没加进来,先列一个表可以比较清楚的查看,也方便给大家查找.如果有哪些题目的链接有错误,请大家留言和谅解,链多了会眼花.  # Title Acceptance Difficulty  617  Merge Two Binary  69.9%  Easy  606  Construct String from Binary Tree  52.0%  Easy  599  Minimum Index Su

LeetCode算法题-Minimum Distance Between BST Nodes(Java实现-四种解法)

这是悦乐书的第314次更新,第335篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第183题(顺位题号是783).给定具有根节点值的二叉搜索树(BST),返回树中任何两个不同节点的值之间的最小差值.示例: 给定的树[4,2,6,1,3,null,null]由下图表示: 4 / 2 6 / \ 1 3 输出:1 说明:请注意,root是TreeNode对象,而不是数组.该树中的任意节点最小差值为1,它发生在节点1和节点2之间,也发生在节点3和节点2之间. 注意: BS

LeetCode算法题-Next Greater Element I(Java实现)

这是悦乐书的第244次更新,第257篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第111题(顺位题号是496).你有两个数组(没有重复)nums1和nums2,其中nums1的元素是nums2的子集.在nums2的相应位置找到nums1元素的所有下一个更大的数字.nums1中的数字x的下一个更大数字是nums2中右边第一个更大的数字.如果它不存在,则输出该数字的-1.例如: 输入:nums1 = [4,1,2],nums2 = [1,3,4,2]. 输出:[-1,

LeetCode算法题-Find Mode in Binary Search Tree(Java实现)

这是悦乐书的第246次更新,第259篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第113题(顺位题号是501).给定具有重复项的二叉搜索树(BST),找到给定BST中的所有模式(最常出现的元素).假设BST定义如下: 节点的左子树仅包含键小于或等于节点键的节点. 节点的右子树仅包含键大于或等于节点键的节点. 左右子树也必须是二叉搜索树. 例如: 鉴于BST [1,null,2,2], 1 2 / 2 返回[2]. 注意:如果树有多个模式,您可以按任何顺序返回它们.

LeetCode算法题-Convert BST to Greater Tree(Java实现)

这是悦乐书的第255次更新,第268篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第122题(顺位题号是538).给定二进制搜索树(BST),将其转换为更大树,使原始BST的每个键都更改为原始键加上所有键的总和大于BST中的原始键.例如: 输入:二进制搜索树的根,如下所示: 5 / 2 13 输出:大树的根,如下所示: 18 / 20 13 本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试. 0

LeetCode算法题-Shortest Unsorted Continuous Subarray(Java实现)

这是悦乐书的第267次更新,第281篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第134题(顺位题号是581).给定一个整数数组,找到一个连续的子数组,按升序对该子数组进行排序,使得整个数组也按升序排序.找到最短的无序连续子数组并输出其长度.例如: 输入:[2,6,4,8,10,9,15] 输出:5 说明:按升序对[6,4,8,10,9]子数组进行排序,以使整个数组按升序排序. 注意: 数组的长度在[1,100]范围内. 数组可能包含重复项,因此这里的升序表示<=

LeetCode算法题-Count Binary Substrings(Java实现)

这是悦乐书的第293次更新,第311篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第161题(顺位题号是696).给定一个字符串s,计算具有相同数字0和1的非空且连续子串的数量,并且这些子串中的所有0和所有1都是连续的.重复出现的子串也计算在内.例如: 输入:"00110011" 输出:6 说明:有6个子串具有相同数量的连续1和0:"0011","01","1100","10"

LeetCode算法题-Merge Sorted Array(Java实现)

这是悦乐书的第161次更新,第163篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第20题(顺位题号是88).给定两个排序的整数数组nums1和nums2,将nums2中的元素合并到nums1中,并且作为一个排序的数组.在nums1和nums2中初始化的元素个数分别为m和n.假设nums1有足够的空间(大于或等于m + n)来保存nums2中的其他元素.例如: 输入:nums1 = [1,2,3,0,0,0],m = 3,nums2 = [2,5,6],n = 3