棧 Stack
寫在開頭
- 線性結構,棧操作是數組操作的子集
- 先進後出的數據結構(LIFO),只能從一端添加元素,也只能從一端取出元素,這一端稱爲棧頂
棧的實現:複用動態數組,採用接口的方式進行構造ArrayStack<E>
-
Stack接口:
public interface Stack<E> { /** * 獲取棧內元素容量 * @return */ int getSize(); /** * 棧空判斷 * @return */ boolean isEmpty(); /** * 入棧 * @param e */ void push(E e); /** * 出棧 * @return */ E pop(); /** * 獲取棧頂元素 * @return */ E peek(); }
-
接口實現類:ArrayStack<E>
public class ArrayStack<E> implements Stack<E> { private Array<E> array; public ArrayStack(int capacity) { array = new Array<>(capacity); } public ArrayStack() { array = new Array<>(); } public int getCapacity() { return array.getCapacity(); } @Override public int getSize() { return array.getSize(); } @Override public boolean isEmpty() { return array.isEmpty(); } @Override public void push(E e) { array.addLast(e); } @Override public E pop() { // 等同於:array.remove(size - 1); return array.removeLast(); } @Override public E peek() { // 等同於:array.get(size - 1); return array.getLast(); } @Override public String toString() { return "stack.ArrayStack{" + "array=" + array + '}'; } }
應用
- 編輯器 - Undo(撤銷)操作:Undo操作永遠撤銷的是當前一步操作的上一步操作,從操作棧中依次執行出棧操作。
- 操作系統 - 系統調用棧:記錄程序嵌套指令執行中斷點,將中斷點記錄壓入棧內(類比子函數執行點,重複子函數執行點入棧操作,直到調用至最底層子函數爲止),出棧操作便是對底層中斷點結果進行依次返回的操作。
- 編輯器 - 括號匹配,以力扣-T20題目爲例:
-
題面:
給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。 有效字符串需滿足: 左括號必須用相同類型的右括號閉合。 左括號必須以正確的順序閉合。 注意空字符串可被認爲是有效字符串。
-
題解:利用棧的特性,掃描給定字符串字符元素,對左括號類別字符(
(
、[
、{
),執行入棧操作,對於非左括號類別字符:取棧頂元素進行配對邏輯判斷,配對成功並且遍歷結束後棧爲空作爲匹配成功。import java.util.Stack; class Solution { public boolean isValid(String s) { Stack<Character> stack = new Stack<>(); for (int i = 0; i < s.length(); i ++) { char c = s.charAt(i); if (c == '(' || c =='[' || c == '{') { stack.push(c); } else { if (stack.isEmpty()) { return false; } if (c == ')' && stack.pop() != '(') { return false; } if (c == ']' && stack.pop() != '[') { return false; } if (c == '}' && stack.pop() != '{') { return false; } } } return stack.isEmpty(); } }
-