牛客试题:包含min函数的栈

牛客试题:包含min函数的栈

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

此栈包含的方法有:
push(value):将value压入栈中
pop():弹出栈顶元素
top():获取栈顶元素
min():获取栈中最小元素

数据范围:操作数量满足0≤n≤300 ,输入的元素满足 ∣val∣≤10000
进阶:栈的各个操作的时间复杂度是O(1) ,空间复杂度是 O(n)

示例:
输入: [“PSH-1”,“PSH2”,“MIN”,“TOP”,“POP”,“PSH1”,“TOP”,“MIN”]
输出: -1,2,1,-1
解析:
"PSH-1"表示将-1压入栈中,栈中元素为-1
"PSH2"表示将2压入栈中,栈中元素为2,-1
“MIN”表示获取此时栈中最小元素==>返回-1
"TOP"表示获取栈顶元素==>返回2
"POP"表示弹出栈顶元素,弹出2,栈中元素为-1
"PSH1"表示将1压入栈中,栈中元素为1,-1
"TOP"表示获取栈顶元素==>返回1
“MIN”表示获取此时栈中最小元素==>返回-1

示例1
输入:
[“PSH-1”,“PSH2”,“MIN”,“TOP”,“POP”,“PSH1”,“TOP”,“MIN”]
复制
返回值:
-1,2,1,-1

答案使用了Stack类来辅助实现了O(1)的复杂度Top,Min等函数。其实也可以只使用数组来实现。
思路:由于输入范围小于300,那么可以使用数组来实现栈。将0位置作为栈底即可,使用变量num指向当前数组元素的下标即可,压栈操作就是在num+1个位置放置元素,出栈就是将num减一。
Top的实现也很简单,返回当前的num位置的值即可。主要是Min的实现,如果去遍历数组的话,复杂度就是O(n),不是O(1)。为了实现O(1),可以再使用一个栈来保存min的值。
可以这样理解,有一个栈m,m里面保存的是历史的最小值,比如第一个元素进来,第一个元素就是最小的,这个元素入栈,如果第二个元素进来并且比第一个元素小,那么将第二个元素入栈,那么栈顶总是最小的元素。如果第二个需要出栈,那么将这个元素和m的栈顶元素进行比较,如果相等,那么表明当前弹出的元素是最小的元素,需要更新栈顶(即将栈顶元素弹出)。
总之,栈m的栈顶始终是最小的元素。
代码如下:

import java.util.*;

public class Solution {
    int[] stack = new int[300];//栈的数组实现
    int num = -1;//指向栈顶位置
    int[] min = new int[300];//维护最小值,栈顶始终是目前最小的元素
    int indexMin = -1;//指向min的顶部
    public void push(int node) {
    	//入栈
        num++;
        stack[num] = node;
        //维护最小值
        //储存最小值的栈为空的情况
        //将第一个元素进行储存
        if(indexMin == -1){
            min[0] = node;
            indexMin++;
        }else{
        	//其余情况,更新最小值
        	//主要是相等也要保存下来,因为
        	//当删除元素等于最小值时,是会删除最小值的
        	//如果相等的不保留,那么最小值就会变化
            if(node<=min[indexMin]){
                indexMin++;
                min[indexMin] = node;
            }
        }
        
    }
    
    public void pop() {
    	//出栈,如果出栈的元素是最小值,那么既要更新栈又要更新最小值
        if(stack[num]==min[indexMin]){
            indexMin--;
        }
        num--;
    }
    
    public int top() {
        return stack[num];
    }
    
    public int min() {
        return min[indexMin];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值