数据结构与算法---(最小栈)

Posted 雾晴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法---(最小栈)相关的知识,希望对你有一定的参考价值。

最小栈

题目需求:

实现一个这样的栈,这个栈除了可以进行普通的push、pop操作以外,还可以进行getMin的操作,getMin方法被调用后,会返回当前栈的最小值。栈里面存放的都是 int 整数,
力扣题目:实现一个最小栈

暴力版本实现

时间复杂度为O(n);空间复杂度为O(1)
采用一个指针来指向最小元素下标,每次出栈都要判断出栈元素是否是当前最小,如果是就要去遍历,更新最小指针,

class MinStack 
    int[] nums;
    int minIndex;
    int index;

    /** initialize your data structure here. */
    public MinStack() 
        this.nums=new int[20000];
        this.index=0;
        this.minIndex=-1;
        
    public void push(int x) 
        nums[index]=x;
        index++;
        if(minIndex==-1)
            minIndex=0;
        else if(x<nums[minIndex])
            minIndex=index-1;
        
    
    
    public void pop() 
        index--;
        if(index==minIndex)
            minIndex=0;
            for(int i=0;i<index;i++)
                if(nums[i]<=nums[minIndex])
                    minIndex=i;
                
            
        
        
    
    
    public int top() 
        return nums[index-1];
    
    
    public int min() 
        return nums[minIndex];
    

辅助栈实现

采用一个辅助栈来实现,其时间复杂度为O(1),空间复杂度为O(n)
有两个栈 s1和 s2,s1 是目标栈,s2 是辅助栈,用来存放最小值。

  1. 每次 getMin 的时候,直接从 s2 栈顶获取即可
  2. 每次入栈,s1直接入栈,s2则需要判断,若当前入栈元素小于s2的栈顶元素,则直接入栈,若当前元素大于等于s2的栈顶元素,则把s2的栈顶元素值,入栈一次。
  3. 每次出栈,s1,s2都直接弹出即可
  4. 需要注意,若首次入栈,也可以当s2为空栈的时候,直接将当前元素入栈
class MinStack 
    Stack<Integer> s1;
    Stack<Integer> s2;
    /** initialize your data structure here. */
    public MinStack() 
        this.s1=new Stack<Integer>();
        this.s2=new Stack<Integer>();
        
    public void push(int x) 
        s1.push(x);
        if(s2.empty())
            s2.push(x);
        else
            if(x<s2.peek())
            s2.push(x);
            else
                s2.push(s2.peek());
            
        
    
    
    public void pop() 
        s1.pop();
        s2.pop();
    
    
    public int top() 
        return s1.peek();
    
    
    public int min() 
        return s2.peek();
    

使用存差值实现(最优)
public class MinStack 

    private Stack<Integer> stack = new Stack<Integer>();
    private int min;

    public void push(int x) 
        if (stack.isEmpty()) 
            min = x;
            stack.push(0);
         else 
            // 计算差值
            int compare = x - min;
            stack.push(compare);
            // 如果差值小于0,显然 x 成为最小值,否则最小值不变
            min = compare < 0 ? x : min;
        
    

    public void pop() 
        int top = stack.peek();
        // 如果top小于0,显然最小值也一并会被删除,此时更新最小值
		
        min = top < 0 ? (min - top) : min;
        stack.pop();
    

    public int getMin() 
        return min;
    
 

以上是关于数据结构与算法---(最小栈)的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法之深入解析“最小栈”的求解思路与算法示例

POJ 3552 Slim Span (最小差值生成树)

单调队列&单调栈归纳

python kayb算法之从一组序列当中获取一组与目标值最接近的算法

数据结构与算法面试题包含min函数的栈

数据结构与算法面试题包含min函数的栈