想了解更多數據結構以及算法題,可以關注微信公衆號“數據結構和算法”,每天一題爲你精彩解答。也可以掃描下面的二維碼關注
基礎知識
棧也是一種特殊的線性表,他只能對棧頂進行添加和刪除元素。棧有入棧和出棧兩種操作,他就好像我們把書一本本的摞起來,最先放的書肯定是摞在下邊,最後放的書肯定是摞在了最上面,摞的時候不允許從中間放進去,拿書的時候也是先從最上面開始拿,不允許從下邊或中間抽出來。
棧的原理圖
棧的實現可以使用數組也可以使用鏈表,我們這裏分析的主要是使用數組的形式。
代碼實現
棧的實現其實非常簡單,常見的就兩種操作,一種是壓棧一種是出棧,我們來看下代碼
public class Stack<E> {
private Object[] data;
private int size;
public Stack(int capacity) {
if (capacity <= 0)
throw new IllegalArgumentException("棧的大小必須大於0");
data = new Object[capacity];
}
public void push(E item) {
if (isFull())
throw new IllegalArgumentException("棧已經滿了");
data[size++] = item;
}
public E pop() {
if (isEmpty())
throw new IllegalArgumentException("棧是空的");
E temp = (E) data[--size];
data[size] = null;
return temp;
}
public E peek() {
if (isEmpty())
throw new IllegalArgumentException("棧是空的");
return (E) data[size - 1];
}
public boolean isEmpty() {
return size() == 0;
}
public boolean isFull() {
return size() == data.length;
}
public int size() {
return size;
}
}
這裏爲了方便,棧的空間大小在初始化的時候就就已經固定了,並且棧滿的時候沒有擴容,棧是一個非常有用的數據結構,尤其在算法中用到的還是比較多的。棧是一種先進後出的數據結構,他和隊列正好相反,隊列是一種先進先出的數據結構。
例子
我們來看個非常簡單的例子,驗證括號的有效性,括號只包含"(",")","[","]","{","}"這6個字符,比如(),{()},{}都是有效的,而{],{(]}都是無效的。
我們來分析一下這道題,當我們遍歷到括號的左半邊的時候,我們把括號的右半邊壓棧,當我們遍歷到括號右半邊的時候,我們就把棧頂的元素彈出,然後在和我們遍歷的符號比較看是否一樣,我們以字符串"{()}"爲例來畫圖分析一下,
搞懂了上面的圖,寫出代碼就容易多了,我們來看下代碼怎麼實現
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>(s.length());
for (char c : s.toCharArray()) {
if (c == '(')
stack.push(')');
else if (c == '{')
stack.push('}');
else if (c == '[')
stack.push(']');
else if (stack.isEmpty() || stack.pop() != c)
return false;
}
return stack.isEmpty();
}