數據結構學習—— 棧(stack)java
棧(stack)是一種運算受限的線性數據結構,運算受限指的是棧這種數據結構僅容許在一端添加元素,刪除元素,這一端被稱做棧頂,相對應的另外一端則稱爲棧底。如圖所示:
git
當咱們在文檔編輯器中輸入文字,當發現輸入錯誤時,想要撤銷到前一步,這個操做就是Undo。撤銷的原理實際上就是棧這種數據結構來設計實現的。例如:李雷在某個文檔編輯器上輸入文字「我愛韓梅梅」,結果,因爲李雷滿腦子想的都是韓梅梅的音容笑貌,不當心將內容輸入成了「我愛含梅梅」。李雷想將內容恢復到「我愛」 這一步,因此他按了三次「Ctrl+z」,而後又依次將「韓」,「梅」,「梅」三個字輸入了進去。
github
來看一個C語言的問題:算法
#include<stdio.h>
int main(void){
int i=1;
printf("%d%d%d",i,i++,i++);
return 0;
}
複製代碼
這個程序的運行結果是什麼?若是隻是知道i++與++i的區別是不足以解決這道問題的。先公佈答案,這個程序的運行結果爲:321,這與printf的底層原理有關,由於printf的底層實現就是棧。仍是拿李雷韓梅梅來舉例說明。數組
printf("我愛韓梅梅");
複製代碼
printf函數首先會將字符串內容從右至左 push到棧中。bash
有以下程序:數據結構
A();
function A(){
1 ...
2 B();
3 ...
4 end
}
function B(){
1 ...
2 C();
3 ...
4 end
}
function C(){
1 ...
2 ...
3 ...
4 end
}
複製代碼
程序從A方法開始調用,執行到 A方法的第二行,計算機發現須要執行B方法,這時就會將執行到哪一步這樣一個信息壓入到系統棧中。例如,定義A2爲A方法的第二行,計算機此時將A2壓入系統棧,代表執行到了A方法的第二行。
編輯器
本文中ArrayStack的底層實現數組爲動態數組:動態數組,DobbyKim's Blog。
函數
public interface Stack<E> {
void push(E e);
E pop();
E peek();
int getSize();
boolean isEmpty();
}
public class ArrayStack<E> implements Stack<E>{
Array<E> array;
public ArrayStack(int capacity){
array = new Array<>(capacity);
}
public ArrayStack(){
array = new Array<>();
}
public void push(E e){...}
public E pop(){...}
public int getSize(){...}
public int getCapacity(){...}
public boolean isEmpty(){...}
public E peek(){...}
public String toString(){...}
}
複製代碼
點擊查看源碼
ArrayStack的方法push 與 pop 的均攤時間複雜度爲O(1),由於這裏面涉及到底層實現Array爲動態數組,resize()擴容操做爲一個O(n)的算法。getSize()方法,peek()方法,isEmpty()方法的時間複雜度均爲O(1)。學習
給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。
有效字符串需知足:
左括號必須用相同類型的右括號閉合。
左括號必須以正確的順序閉合。
注意空字符串可被認爲是有效字符串。
輸入: "()"
輸出: true
複製代碼
輸入: "()[]{}"
輸出: true
複製代碼
輸入: "(]"
輸出: false
複製代碼
輸入: "([)]"
輸出: false
複製代碼
輸入: "{[]}"
輸出: true
複製代碼
問題解決思路:棧。只要是左側的括號爲'(','[','{'就push到棧中,遇到與之匹配的右側括號則pop,最後棧若是爲空則說明匹配成功。Java代碼以下:
import java.util.Stack
class Solution {
public boolean isValid(String s) {
Stack<Character>stack = new Stack<>();
for(int i=0;i<s.length();i++){
if(s.charAt(i)=='(' || s.charAt(i)=='[' || s.charAt(i)=='{'){
stack.push(s.charAt(i));
}else{
if(stack.isEmpty())
return false;
char c = stack.pop;
if(s.charAt(i)==')' && c!='(')
return false;
if(s.charAt(i)==']' && c!='[')
return false;
if(s.charAt(i)=='}' && c!='{')
return false;
}
}
return stack.isEmpty();
}
}
複製代碼