class 015 最小栈

这篇文章是看了“左程云”老师在b站上的讲解之后写的, 自己感觉已经能理解这个题目了, 所以就将整个过程写下来了。

这个是“左程云”老师个人空间的b站的链接, 数据结构与算法讲的很好很好, 希望大家可以多多支持左程云老师, 真心推荐.
https://space.bilibili.com/8888480?spm_id_from=333.999.0.0

顺便提供一下测试链接:
https://leetcode.cn/problems/min-stack/
在这里插入图片描述

1. 逻辑结构实现

  1. 我们需要设置两个 , 一个 data栈, 另一个 min栈, data栈 是用来存放所有存入的数据的, min栈 是用来存放所有放入的数据的过程中最小的数据的.
  2. 如何使用这两个 , 有三种情况:(注意看题目要求:最小值是 data栈 中剩下的数据中最小的值.)
    1. 若是第一次放入数据, 直接将这个“数据”同时放入这两个 .
    2. 若是 新放入的数据 <= min栈栈顶元素, 就将这个“数据”同时放入 data栈 和 min栈.
    3. 若是 新放入的数据 > min栈栈顶元素, 就将这个“数据”放入 data栈, 但是放入 min栈 中的是 min栈中的栈顶元素.
  3. 这样的实现, 无论怎么进行弹出, min栈 中的栈顶元素一定是 data栈中 数据的最小值.

过程如下图:自己画图实现一下就理解了.

在这里插入图片描述

2. 代码实现

2.1 第一种方式

关于每一个方法的实现, 我都在对应的地方写上了注释, 应该是能看懂, 过程也在逻辑结构分析的地方写清楚了.

注意:因为这个实现方式使用的是 JDK 中自带的栈, 所以常数时间不是很好, 第二种直接使用 数组, 这样就比较快.

// 提交时把类名、构造方法改成MinStack  
class MinStack1 {  
    public Stack<Integer> data;  
    public Stack<Integer> min;  
  
    public MinStack1() {  
       data = new Stack<Integer>();  
       min = new Stack<Integer>();      // 使用JDK自带的栈.  
    }  
  
    public void push(int val) {  
       data.push(val);                  // 不管怎么样, data栈是一定要放入的.  
       if (min.isEmpty() || val <= min.peek()) {   // 当“min栈”为“空”的时候, 或者“放进来的数字” <= “min栈栈顶元素”  
          min.push(val);                          // 将“放进来的数据放入min栈”.  
       } else { // !min.isEmpty() && val > min.peek()     // 若是反过来, min不为“空”, 并且“放进来的数字” > “min栈栈顶元素”  
          min.push(min.peek());                   // 将“min栈栈顶元素放入min栈”.  
       }  
    }  
  
    public void pop() {          // 弹出就将两个栈的栈顶元素同时弹出,  
       data.pop();              // 因为题目需要的是“data栈中”剩下的数据中最小的.   
	   min.pop();  
    }  
  
    public int top() {  
       return data.peek();  
    }  
  
    public int getMin() {  
       return min.peek();     // “min栈”中栈顶元素一定是“data栈”剩下的数据中最小的.  
    }  
}

2.2 第二种方式

这个和上面的原理是一模一样的, 就是实现栈的时候使用的是自己制作的 数组, 基本上没什么可讲的, 甚至注释可以直接照搬下来, 所以这里就不再多此一举, 再抄一遍注释, 而且第二种方式用数组的时候需要开多大, 左程云老师的代码注释里写了, 也就不多说了.

// 提交时把类名、构造方法改成MinStack  
class MinStack2 {  
    // leetcode的数据在测试时,同时在栈里的数据不超过这个值  
    // 这是几次提交实验出来的,哈哈  
    // 如果leetcode补测试数据了,超过这个量导致出错,就调大  
    public final int MAXN = 8001;  
  
    public int[] data;  
    public int[] min;  
    int size;  
  
    public MinStack2() {  
       data = new int[MAXN];  
       min = new int[MAXN];  
       size = 0;           // 数组的长度大小  
    }  
  
    public void push(int val) {  
       data[size] = val;  
       if (size == 0 || val <= min[size - 1]) {   
min[size] = val;  
       } else {  
          min[size] = min[size - 1];  
       }  
       size++;  
    }  
  
    public void pop() {  
       size--;  
    }  
  
    public int top() {  
       return data[size - 1];  
    }  
  
    public int getMin() {  
       return min[size - 1];  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值