1-1 帶有getmin功能的棧

題目描述

  • 實現一個特殊的棧,在實現棧基本功能的基礎上,再實現返回棧中最小元素的操作。
  • 要求push,pop,getmin的操作時間複雜度都是 1。
  • 設計的棧類型可以使用現成的棧結構。

解題嘗試

  • 自己最初的設想是在棧中增加一個成員變量min,用來記錄最小值,每入棧一個元素就把這個元素和min比較,如果小於min就更新min的值。
  • 但是如果值爲min的那個最小元素出棧了,那麼就無法判斷當前棧中哪個元素最小,所以不可行。

解題方法1

  • 除了實現基本功能的棧stack1之外,我們再定義一個棧stack2,用它來記錄每一步的最小值。
  • 當stack1入棧了一個元素x,我們比較x與stack2的棧頂元素top的大小,如果x<=top,將x入棧到stack2,否則不進行處理。
  • 當stack1出棧一個元素(棧頂)x,我們比較x與stack2的棧頂元素top的大小,如果x==top,將stack2也出棧,否則不進行處理。
  • 這樣stack2的棧頂始終保存着stack1的最小值,實現getmin方法只需要返回stack2棧頂即可。
    在這裏插入圖片描述
  • 實現代碼
class stack{
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;
    stack(){
        this.stack1 = new Stack<>();
        this.stack2 = new Stack<>();
    }
    public void push(int x){
        this.stack1.push(x);
        if(this.stack2.empty() || x<=this.stack2.peek()){
           this.stack2.push(x);
        }
    }
    public Integer pop(){
        if(this.stack1.empty()){
            throw new RuntimeException("stack empty");
        }
       int e = this.stack1.pop();
       if(e == this.stack2.peek()){
           this.stack2.pop();
       }
       return e;
    }
    public Integer getmin(){
        if(this.stack2.empty()){
            throw new RuntimeException("stack empty");
        }
        return this.stack2.peek();
    }
}

解題方法2

  • 可以發現解題方法1中棧stack2中的元素數量少於stack1中元素數量,這樣每次出棧的時候都要將stack1的棧頂與stack2的棧頂比較一下。
  • 我們也可以這樣實現,在stack1入棧的時候,如果入棧元素x大於stack2的棧頂,就將stack2的棧頂再次入棧到stack2。這樣可以使得stack2的元素數量與stack1是同步的,出棧的時候直接兩個棧都進行出棧就好了。
    在這裏插入圖片描述
  • 代碼如下:
class stack{
    private Stack<Integer> stack1;
    private Stack<Integer> stack2;
    stack(){
        this.stack1 = new Stack<>();
        this.stack2 = new Stack<>();
    }
    public void push(int x){
        this.stack1.push(x);
        if(this.stack2.empty() || x<=this.stack2.peek()){
           this.stack2.push(x);
        }
        if(x>this.stack2.peek()){
            this.stack2.push(this.stack2.peek());
        }
    }
    public Integer pop(){
        if(this.stack1.empty()){
            throw new RuntimeException("stack empty");
        }
        int e = this.stack1.pop();
        this.stack2.pop();
       return e;
    }
    public Integer getmin(){
        if(this.stack2.empty()){
            throw new RuntimeException("stack empty");
        }
        return this.stack2.peek();
    }
}
  • 兩個方法的基本思路是一樣的,都是使用stack2記錄stack1每一步的最小值,兩個方法的時間複雜度都爲1,空間複雜度都爲n。
  • 唯一的區別是,方法1中stack2入棧時稍省空間,出棧時稍費時間。方法2中stack2入棧時稍費空間,入棧時稍省時間。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章