劍指offer:包含min函數的棧(java)

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

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

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

    分析到這裏我們發現僅僅添加一個成員變量存放最小元素是不夠的,也就是說當最小元素彈出棧的時候,我們希望能夠得到次小元素。因此在壓入這個最小元素之前,我們要把次小元素保存起來。因此,在壓入這個最小元素之前,我們要把次小元素保存起來。因此我們可以把每次的最小元素都保存起來放到另一個輔助棧裏。

    我們不妨舉幾個例子來分析一下把元素壓入或者彈出棧的過程。


    從表4.1我們可以看出,如果每次都把最小元素壓入輔助棧,那麼就能保證輔助棧的棧頂一直都是最小元素。當最小元素從數據棧內彈出之後,同時彈出輔助棧的棧頂元素,此時輔助棧的新棧頂元素就是下一個最小值。

class ListNode<K>{  
    K data;  
    ListNode<K> nextNode;  
}  
public class MyStack<K> {  
    /** 
     * 定義棧的數據結構,請在該類型中實現一個能夠得到棧的最小元素的min函數 
     * 在該棧中,min、push、pop的時間複雜度都是O(1) 
     */  
    public ListNode<K> head;  
    public int length;  
    public void push(K item){  
        ListNode<K> node = new ListNode<K>();  
        node.data = item;  
        node.nextNode = head;  
        head = node;  
        length++;  
    }  
    public K pop(){  
        if(head == null)  
            return null;  
        ListNode<K> temp = head;  
        head = head.nextNode;  
        length--;  
        return temp.data;  
    }  
      
}  

private MyStack<Integer> minStack = new MyStack<>();  
private MyStack<Integer> dataStack = new MyStack<>();  
public void push(Integer item){  
        dataStack.push(item);  
        if(minStack.length == 0 || item<=minStack.head.data){  
            minStack.push(item);  
        }else{  
            minStack.push(minStack.head.data);  
        }  
    }  
    public Integer pop(){  
        if(dataStack.length == 0 || minStack.length == 0){  
            return null;  
        }  
        minStack.pop();  
        return dataStack.pop();  
    }  
    public Integer min(){  
        if(minStack.length == 0){  
            return null;  
        }  
        return minStack.head.data;  
    }  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章