劍指Offer(Java版):包含min函數的棧

題目:定義棧的數據結構,請在該類型中實現一個可以獲得棧的最小元素的min函數。在該棧中,調用min,push及pop的時間複雜度都是O(1).java

看到這個問題,咱們的第一反應多是每次壓入一個新元素進棧時,將棧裏的全部元素排序,讓最小的元素位於棧頂,這樣就能在O(1)時間獲得最小元素了。但這種思路不能保證最後壓入的元素可以最早出棧,所以這個數據結構已經不是棧了。node

咱們接着想到在棧裏添加一個成員變量存放最小的元素。每次壓入一個新元素進棧的時候,若是該元素比當前最小的元素還要小,則更新最小元素。面試官聽到這種思路以後就會問:若是當前最小的元素被彈出棧了,如何獲得下一個最小的元素呢?面試

分析到這裏咱們發現僅僅添加一個成員變量存放最小元素是不夠的,也就是說當最小元素彈出棧的時候,咱們但願可以獲得次小元素。所以在壓入這個最小元素以前,咱們要把次小元素保存起來。所以,在壓入這個最小元素以前,咱們要把次小元素保存起來。數據結構

是否是能夠把每次的最小元素都保存起來,放在另一個輔助棧裏呢?咱們不妨舉幾個例子來分析一下把元素壓入或者彈出棧的過程。函數

 

題關鍵在於用輔助棧儲存什麼值。要保證輔助棧的top是最小值,pop以後的頂部仍然是最小值。也就是說輔助棧從上到下存儲的應該是最小值->次小值->次次小值……排序

這裏容易進入一個誤區就是:難道輔助棧就是對數據棧的排序?若是真是這樣,push的時候由於要排序不能知足O(1);數據棧pop的時候,輔助棧要先查找數據棧pop出去的值而後再pop,也不知足O(1)。class

當兩個棧爲空時,push進去的第一個值即爲最小值;import

push第二個元素時,若push的值<輔助棧頂元素(此處即第一個值),則將此值壓進輔助棧;若push的值大於等於輔助棧頂元素,則將輔助棧頂元素再次push進去。變量

pop的時候,數據棧輔助棧均彈出頂元素。im

實現代碼以下:

 

package cglib;

import java.util.Stack;

 

public class DeleteNode {
    Stack<Integer> stack1 = new Stack<Integer>(); // 數據棧
    Stack<Integer> stack2 = new Stack<Integer>(); // 輔助棧 用於返回min值
    
    
        public void push(int node) {
             stack1.push(node);
        if (stack2.empty()) {
                stack2.push(node);
            } else {
               if (node < stack2.peek().intValue())//若是進入的數小於輔助棧的棧頂元素
                   stack2.push(node);//則放進去進入的數
                 else stack2.push(stack2.peek());//不然放進輔助棧的棧頂元素
            }
    
        }
    
        @SuppressWarnings("null")
        public int pop() {
            
            if(stack1.empty()||stack2.empty()){
                
                return (Integer) null;
                }
                stack2.pop();
                return stack1.pop();
                }
       
    
        public int top() {
            if (!stack1.empty())
               return stack1.peek().intValue();
            else return 0;
         }
    
        public int min() {
            if (!stack2.empty())
                return stack2.peek().intValue();
            else return 0;
        }
    
        
    
            public static void main(String[] args) {
    
                DeleteNode ms = new DeleteNode();
    
                ms.push(4);
    
                ms.push(3);

                ms.push(1);
    
                ms.push(5);
    
                ms.push(2);//4,3,1,5,2
    
                
                //System.out.println("pop:" +ms.pop() );
                System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );       
    
                System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );       
    
               System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );
               System.out.println("min:" + ms.min() + "  pop:" +ms.pop() );
    
        
    
            }
}

 

輸出:

min:1  pop:2 min:1  pop:5 min:1  pop:1 min:3  pop:3

相關文章
相關標籤/搜索