題目一:有效的括號
問題描述
給定一個只包括 '(',')','{','}','[',']' 的字串,判斷字串是否有效。
解題思路
這道題讓我們驗證輸入的字串是否為括號字串,包括大括號,中括號和小括號。
這裡我們使用棧。
- 遍歷輸入字串
- 如果當前字元為左半邊括號時,則將其壓入棧中
- 如果遇到右半邊括號時,分類討論:
- 1)如棧不為空且為對應的左半邊括號,則取出棧頂元素,繼續迴圈
- 2)若此時棧為空,則直接返回 false
- 3)若不為對應的左半邊括號,反之返回 false
動畫演示
程式碼實現
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
char[] chars = s.toCharArray();
for (char aChar : chars) {
if (stack.size() == 0) {
stack.push(aChar);
} else if (isSym(stack.peek(), aChar)) {
stack.pop();
} else {
stack.push(aChar);
}
}
return stack.size() == 0;
}
private boolean isSym(char c1, char c2) {
return (c1 == '(' && c2 == ')') || (c1 == '[' && c2 == ']') || (c1 == '{' && c2 == '}');
}
}
複製程式碼
題目二:用兩個棧實現佇列
問題描述
用兩個棧來實現一個佇列,完成佇列的 Push 和 Pop 操作。
解題思路
in 棧用來處理入棧(push)操作,out 棧用來處理出棧(pop)操作。一個元素進入 in 棧之後,出棧的順序被反轉。當元素要出棧時,需要先進入 out 棧,此時元素出棧順序再一次被反轉,因此出棧順序就和最開始入棧順序是相同的,先進入的元素先退出,這就是佇列的順序。
- push 元素時,始終是進入棧,pop 和 peek 元素時始終是走出棧。
- pop 和 peek 操作,如果出棧為空,則需要從入棧將所有元素移到出棧,也就是調換順序,比如開始push的順序是 3-2-1,1 是最先進入的元素,則到出棧的順序是 1-2-3,那 pop 操作拿到的就是 1,滿足了先進先出的特點。
- pop 和 peek 操作,如果出棧不為空,則不需要從入棧中移到資料到出棧。
程式碼實現
Stack<Integer> in = new Stack<Integer>();
Stack<Integer> out = new Stack<Integer>();
public void push(int node) {
in.push(node);
}
public int pop() throws Exception {
if (out.isEmpty())
while (!in.isEmpty())
out.push(in.pop());
if (out.isEmpty())
throw new Exception("queue is empty");
return out.pop();
}
複製程式碼
題目三:棧的壓入、彈出序列
問題描述
輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否為該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列 1,2,3,4,5 是某棧的壓入順序,序列 4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
解題思路
借用一個輔助的棧,遍歷壓棧順序,先講第一個放入棧中,這裡是 1,然後判斷棧頂元素是不是出棧順序的第一個元素,這裡是 4,很顯然 1≠4 ,所以需要繼續壓棧,直到相等以後開始出棧。
出棧一個元素,則將出棧順序向後移動一位,直到不相等,這樣迴圈等壓棧順序遍歷完成,如果輔助棧還不為空,說明彈出序列不是該棧的彈出順序。
程式碼實現
public boolean IsPopOrder(int[] pushSequence, int[] popSequence) {
int n = pushSequence.length;
Stack<Integer> stack = new Stack<>();
for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) {
stack.push(pushSequence[pushIndex]);
while (popIndex < n && !stack.isEmpty()
&& stack.peek() == popSequence[popIndex]) {
stack.pop();
popIndex++;
}
}
return stack.isEmpty();
}
複製程式碼
題目四:包含 min 函式的棧
問題描述
定義棧的資料結構,請在該型別中實現一個能夠得到棧最小元素的 min 函式。
解題思路
使用兩個 stack,一個作為資料棧,另一個作為輔助棧。其中 資料棧 用於儲存所有資料,而 輔助棧 用於儲存最小值。
舉個?:
-
入棧的時候:首先往空的資料棧裡壓入數字 3 ,此時 3 是最小值,所以把最小值壓入輔助棧。接下來往資料棧裡壓入數字 4 。由於 4 大於之前的最小值,因此只要入資料棧,不需要壓入輔助棧。
-
出棧的時候:當資料棧和輔助棧的棧頂元素相同的時候,輔助棧的棧頂元素出棧。否則,資料棧的棧頂元素出棧。
-
獲得棧頂元素的時候:直接返回資料棧的棧頂元素。
-
棧最小元素:直接返回輔助棧的棧頂元素。
程式碼實現
private Stack<Integer> dataStack = new Stack<>();
private Stack<Integer> minStack = new Stack<>();
public void push(int node) {
dataStack.push(node);
minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node));
}
public void pop() {
dataStack.pop();
minStack.pop();
}
public int top() {
return dataStack.peek();
}
public int min() {
return minStack.peek();
}
複製程式碼
小程式
小程式名稱:圖解劍指offer
劍指offer上面的 66 道題目都挪上去了,每一道題目基本上都有詳細說明解法,更多的解法我還在新增中,需要準備刷題的可以在坐地鐵的零碎時間拿出來看看^_^