編程題彙總_棧

1.括號匹配問題

題目詳述: 有效的括號

解題思路

左括號入棧,右括號出戰,判斷是否匹配。

注意:
1.s = "}" 如果遍歷遍歷過程中,c 不是左括號時,先判斷棧是否爲空(爲空 return false)。
2.s = "{" 遍歷完整個 s ,要判斷此時棧是否爲空(爲空 return true;)。

程序測試

class Solution {
    public boolean isValid(String s) {
        //1.創建棧,保存字符類型
        Stack<Character> stack = new Stack<>();
        //2.循環遍歷整個字符串中的字符
        for(int i = 0; i< s.length(); i ++){
            char c = s.charAt(i);
            //3.左括號入棧
           if(c == '(' || c == '[' || c == '{'){ //注意:""爲字符串 ''爲字符
               stack.push(c);
               continue; //入棧完 直接對下一個字符判斷
           }
           if(stack.empty()){
               return false; //s = ")" 不匹配 棧爲空
           }
           //4.右括號出棧
           char top = stack.pop();
           //5.判斷是否匹配
           //合法情況1
           if(top == '(' && c == ')'){
               continue; //直接對下一個字符判斷
           }
           //合法情況2
           if(top == '[' && c == ']'){
               continue; //直接對下一個字符判斷
           }
           //合法情況3
           if(top == '{' && c == '}'){
               continue; //直接對下一個字符判斷
           }
           //不是上的的三種合法情況 則不合法
           return false; // s = "([)]" 不合法
        }
        if(stack.empty()){ 
            return true;
        }
        return false; // s = "{" 不合法 此時棧不爲空
    }
}

2.合法括號序列判斷

題目詳述:合法括號序列判斷

解題思路

1.碰到")“開始彈出棧頂的”(",如果此時棧爲空,則返回false
2.碰到其他內容直接返回false
3.字符串結尾時,棧非空返回false

程序測試

import java.util.Stack;

public class Parenthesis {
    public boolean chkParenthesis(String A, int n) {
        Stack stack = new Stack();
        for(int i = 0; i<n; i++){
            if (A.charAt(i)!='(' && A.charAt(i)!=')'){ //排除其他字符的情況 (a)
                return false;
            }
            if(A.charAt(i)=='('){
                stack.push(A.charAt(i));
            }
            if(A.charAt(i)==')'){
                if(stack.isEmpty()){ //排除左括號在前的情況 )()
                    return false;
                }
                stack.pop();
            }
        }
        if(stack.isEmpty()){ //排除左括號過多的情況 (()
            return true;
        }
        return false;
    }
}

3.用隊列實現棧

題目詳述

鏈接:用隊列實現棧

思路解析

兩個隊列實現棧。

注意:
        1.入棧:入 A 隊列。
        2.出棧:將隊列 A 中的元素出隊列後入到隊列 B 中,A中的最後一個元素就是此時出棧元素。出棧完將 隊列 B 元素重新出隊列移回隊列 A。

程序測試

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class MyStackBy2Queue {
    private Queue<Integer> A = new LinkedList<>();
    private Queue<Integer> B = new LinkedList<>();

    public void push(int x) {
        // x 往 A 中入隊列即可
        A.offer(x);
    }

    public Integer pop() {
        if (empty()) {
            return null;
        }
        // 把 A 中的元素往 B 中倒騰
        while (A.size() > 1) {
            Integer front = A.poll();
            B.offer(front);
        }
        // 當循環結束之後, A 中應該就是 1 個元素;
        // 這個元素就應該是被出棧的元素
        int ret = A.poll();
        // 交換 A 和 B 的身份
        swapAB();
        return ret;
    }

    private void swapAB() {
        Queue<Integer> tmp = A;
        A = B;
        B = tmp;

//        A = B;
//        B.clear();
    }

    public Integer top() {
        if (empty()) {
            return null;
        }
        // 把 A 中的元素往 B 中倒騰
        while (A.size() > 1) {
            Integer front = A.poll();
            B.offer(front);
        }
        // 當循環結束之後, A 中應該就是 1 個元素;
        // 這個元素就應該是被出棧的元素
        int ret = A.poll();
        B.offer(ret);   // top 和 pop 唯一的區別就是這句話
        // 交換 A 和 B 的身份
        swapAB();
        return ret;
    }

    public boolean empty() {
        return A.isEmpty() && B.isEmpty();
    }
}

4.用棧實現隊列

題目詳述

鏈接:用棧實現隊列

思路解析

兩個棧實現隊列。

入隊列:入棧 A。
出隊列:將A中元素依次出棧再入到棧B,此時B出棧(B棧頂元素即爲返回的元素值),最後將B中的元素依次出棧在入到棧A。

程序測試

import java.util.Stack;

public class MyQueueBy2Stack {
    private Stack<Integer> A = new Stack<>();
    private Stack<Integer> B = new Stack<>();

    public void push(int x) {
        // 把新元素入 A 即可
        A.push(x);
    }

    public Integer pop() {
        // 1. 如果爲空, 就直接返回
        if (empty()) {
            return null;
        }
        // 2. 把 A 中的元素都倒騰給 B
        while (!A.isEmpty()) {
            B.push(A.pop());
        }
        // 3. 針對 B 進行出棧
        int element = B.pop();
		// 4. 再把 B 中的元素都倒騰到 A 裏
        while (!B.isEmpty()) {
            A.push(B.pop());
        }
		return element;
    }

    public Integer peek() {
        // 1. 如果爲空, 就直接返回
        if (empty()) {
            return null;
        }
        // 2. 把 A 中的元素都倒騰給 B
        while (!A.isEmpty()) {
            B.push(A.pop());
        }
        // 3. 直接取 B 的棧頂元素
        int element =  B.peek();
		// 4. 再把 B 中的元素都倒騰到 A 裏
        while (!B.isEmpty()) {
            A.push(B.pop());
        }
		return element;
    }

    public boolean empty() {
        return A.isEmpty();
    }
}

5.實現一個最小棧

題目詳述

鏈接:最小棧

思路解析

定義兩個棧A(正常棧)、B(最小棧)。
A:按正常棧的規則插入刪除元素。
B:存放的是當前棧的最小值(棧頂一定是當前最小值)。

注意:
        1.入棧:先入 A ,後判斷是否入B。如果 B 爲空,直接入棧 B;B不爲空,將入棧元素與 B 的棧頂元素比較(若入棧元素小則將元素入棧 B,否則不入)。
        2.出棧:將 A裏的元素正常出棧,B裏的棧頂元素刪除。
        3.最小值:B 的棧頂元素。

程序測試

import java.util.Stack;

public class MinStack {
    private Stack<Integer> A = new Stack<>();
    private Stack<Integer> B = new Stack<>();

    public void push(int x) {
        A.push(x);
        if (B.isEmpty()) {
            B.push(x);
            return;
        }
        int min = B.peek();
        if (x < min) {
            min = x;
        }
        B.push(min);
    }

    public Integer pop() {
        if (A.isEmpty()) {
            return null;
        }
        B.pop();
        return A.pop();
    }

    public Integer top() {
        if (A.isEmpty()) {
            return null;
        }
        return A.peek();
    }

    public Integer getMin() {
        if (B.isEmpty()) {
            return null;
        }
        return B.peek();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章