劍指offer 棧篇

面試題30.包含min函數的棧(155)

原題

在這裏插入圖片描述

題解

方法一:輔助棧和數據棧同步

在這裏插入圖片描述

//java
class MinStack {
    Stack<Integer> A, B;  //B是輔助棧

    /** initialize your data structure here. */
    public MinStack() {
        A = new Stack<>();
        B = new Stack<>();
    }
    
    public void push(int x) {
        A.push(x);
        if(B.empty() || x <= B.peek()){
            B.push(x);
        }else{
            B.push(B.peek());
        }
    }
    
    public void pop() {
        if(!A.empty()){
            A.pop();
            B.pop();
        }
    }
    
    public int top() {
        return A.peek();
    }
    
    public int min() {
        return B.peek();
    }
}
//java 別人家的代碼   考慮了異常
import java.util.Stack;

public class MinStack {

    // 數據棧
    private Stack<Integer> data;
    // 輔助棧
    private Stack<Integer> helper;

    /**
     * initialize your data structure here.
     */
    public MinStack() {
        data = new Stack<>();
        helper = new Stack<>();
    }

    // 思路 1:數據棧和輔助棧在任何時候都同步

    public void push(int x) {
        // 數據棧和輔助棧一定會增加元素
        data.add(x);
        if (helper.isEmpty() || helper.peek() >= x) {
            helper.add(x);
        } else {
            helper.add(helper.peek());
        }
    }

    public void pop() {
        // 兩個棧都得 pop
        if (!data.isEmpty()) {
            helper.pop();
            data.pop();
        }
    }

    public int top() {
        if(!data.isEmpty()){
            return data.peek();
        }
        throw new RuntimeException("棧中元素爲空,此操作非法");
    }

    public int getMin() {
        if(!helper.isEmpty()){
            return helper.peek();
        }
        throw new RuntimeException("棧中元素爲空,此操作非法");
    }
}

作者:liweiwei1419
鏈接:https://leetcode-cn.com/problems/min-stack/solution/shi-yong-fu-zhu-zhan-tong-bu-he-bu-tong-bu-python-/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

方法二:輔助棧和數據棧不同步

在這裏插入圖片描述

//java
class MinStack {
    Stack<Integer> A, B;  //B是輔助棧

    /** initialize your data structure here. */
    public MinStack() {
        A = new Stack<>();
        B = new Stack<>();
    }
    
    public void push(int x) {
        A.push(x);
        if(B.empty() || x <= B.peek()){   //等號一定要考慮進來
            B.push(x);
        }
    }
    
    public void pop() {
        if(A.peek().equals(B.peek())){
        //if(A.peek() == B.peek()){   //這樣寫不對
        //Java 代碼中,由於 Stack 中存儲的是 int 的包裝類 Integer ,因此需要使用 equals() 代替 == 來比較值是否相等
            B.pop();
        }
        if(!A.empty()){
            A.pop();
        }
    }

	/*  上述的簡化寫法
    public void pop() {
        if(A.pop().equals(B.peek()))
            B.pop();
    }
    */


	/* 用==比較的話,必須先完成自動拆箱
	public void pop() {
        if (!A.isEmpty()) {
            // 注意:聲明成 int 類型,這裏完成了自動拆箱,從 Integer 轉成了 int,因此下面的比較可以使用 "==" 運算符
            // 參考資料:https://www.cnblogs.com/GuoYaxiang/p/6931264.html
            // 如果把 top 變量聲明成 Integer 類型,下面的比較就得使用 equals 方法
            int top = A.pop();
            if(top == B.peek()){
                B.pop();
            }
        }
    }
	*/  
	  
    public int top() {
        return A.peek();
    }
    
    public int min() {
        return B.peek();
    }
}

//Java 別人家的代碼 考慮了異常
import java.util.Stack;

public class MinStack {

    // 數據棧
    private Stack<Integer> data;
    // 輔助棧
    private Stack<Integer> helper;

    /**
     * initialize your data structure here.
     */
    public MinStack() {
        data = new Stack<>();
        helper = new Stack<>();
    }

    // 思路 2:輔助棧和數據棧不同步
    // 關鍵 1:輔助棧的元素空的時候,必須放入新進來的數
    // 關鍵 2:新來的數小於或者等於輔助棧棧頂元素的時候,才放入(特別注意這裏等於要考慮進去)
    // 關鍵 3:出棧的時候,輔助棧的棧頂元素等於數據棧的棧頂元素,纔出棧,即"出棧保持同步"就可以了

    public void push(int x) {
        // 輔助棧在必要的時候才增加
        data.add(x);
        // 關鍵 1 和 關鍵 2
        if (helper.isEmpty() || helper.peek() >= x) {
            helper.add(x);
        }
    }

    public void pop() {
        // 關鍵 3:data 一定得 pop()
        if (!data.isEmpty()) {
            // 注意:聲明成 int 類型,這裏完成了自動拆箱,從 Integer 轉成了 int,因此下面的比較可以使用 "==" 運算符
            // 參考資料:https://www.cnblogs.com/GuoYaxiang/p/6931264.html
            // 如果把 top 變量聲明成 Integer 類型,下面的比較就得使用 equals 方法
            int top = data.pop();
            if(top == helper.peek()){
                helper.pop();
            }
        }
    }

    public int top() {
        if(!data.isEmpty()){
            return data.peek();
        }
        throw new RuntimeException("棧中元素爲空,此操作非法");
    }

    public int getMin() {
        if(!helper.isEmpty()){
            return helper.peek();
        }
        throw new RuntimeException("棧中元素爲空,此操作非法");
    }

}

作者:liweiwei1419
鏈接:https://leetcode-cn.com/problems/min-stack/solution/shi-yong-fu-zhu-zhan-tong-bu-he-bu-tong-bu-python-/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

面試題31.棧的壓入、彈出序列(946.驗證棧序列)

題目

在這裏插入圖片描述

安安解法:代碼有些繁瑣

//java 安安 2020.4.24
class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack = new Stack<>();
        int i = 0, j = 0;
        while(j < popped.length){   //結束的條件是:popped數組所有數值都滿足條件
            //System.out.println("i=" + i + ", j=" + j);
            //pushed數組中的元素還沒有遍歷完,需要綜合考慮pushed數組中的值和stack
            if(i < pushed.length){   
                if(pushed[i] != popped[j]){
                    if(!stack.empty() && stack.peek().equals(popped[j])){
                        stack.pop();                       
                        j++;
                    }else{
                        stack.push(pushed[i]);                       
                        i++;
                    }               
                }else{
                    j++;
                    i++;
                }
            }else{    //pushed數組中的元素已經遍歷完,只需要考慮stack中的數值即可  
                int topE =  stack.peek();
                if(!stack.empty() && topE == popped[j]){
                    stack.pop();                  
                    j++;
                }else{
                    return false;
                }
            }
        }
        return true;  //popped數組所有數值都滿足條件
    }
} 

官解

在這裏插入圖片描述

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int N = pushed.length;
        Stack<Integer> stack = new Stack();

        int j = 0;
        for (int x: pushed) {
            stack.push(x);
            while (!stack.isEmpty() && j < N && stack.peek() == popped[j]) {
                stack.pop();
                j++;
            }
        }

        return j == N;
    }
}

作者:LeetCode
鏈接:https://leetcode-cn.com/problems/validate-stack-sequences/solution/yan-zheng-zhan-xu-lie-by-leetcode/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章