有效括號-棧 leetcode題庫第二十題
阿新 • • 發佈:2020-12-24
來自力扣題庫第20題
連結:https://leetcode-cn.com/problems/valid-parentheses
給定一個只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字串,判斷字串是否有效。
有效字串需滿足:
左括號必須用相同型別的右括號閉合。
左括號必須以正確的順序閉合。
注意空字串可被認為是有效字串。
示例 1:
輸入: “()”
輸出: true
這個題可以用資料結構裡面的棧進行實現(這是未優化的,優化後使用一個棧就可以,詳情看最下方)
function a($str): bool {
$leftStr = ['[' , '{', '('];//儲存符號為左的
$rightStr = [']', '}', ')'];//儲存符號為右的 這裡需要注意成對的符號,下標要一致
/**
* 這裡使用陣列函式array_push和array_pop進行模擬出入棧操作會比 new SplStack()方式記憶體佔用更低一些
*/
$leftStr = array_flip($leftStr);
$rightStr = array_flip($rightStr);
$left = new SplStack();//初始化儲存符號為左的棧
$right = new SplStack();//初始化儲存符號為右的棧
$len = strlen($str);
//如果長度不是偶數直接返回false
if ($len % 2) {
return false;
}
for ($i = 0; $i < strlen($str); $i++) {
if (isset($leftStr[$str[$i]])) {
$left->push($str[$i]);
} elseif (isset($rightStr[$str[$i]])) {
$right->push($str[$i]);
}
//判斷左符號棧和右符號棧都沒有資料
if (!$left->isEmpty() && !$right->isEmpty()) {
//左符號棧和右符號棧都彈出一個符號進行比較,如果不一樣就再放回去,進行下一次判斷
$leftLs = $left->pop();
$rightLs = $right->pop();
if ($leftStr[$leftLs] != $rightStr[$rightLs]) {
$left->push($leftLs);
$right->push($rightLs);
} elseif (isset($leftStr[$str[$i]])) {//判斷出現類似 “}{”左右符號相反,程式判斷為true的問題
return false;
}
}
}
//如果左符號棧或右符號棧還有資料,就說明為false
if (!$left->isEmpty() || !$right->isEmpty()) {
return false;
}
return true;
}
還有一個更簡潔的辦法,不過這個執行效率不如上述辦法
function b($str): bool {
$count = ceil(strlen($str) / 2);
for ($i = 0; $i < $count; $i++) {
$str = str_replace("{}", "", $str);
$str = str_replace("[]", "", $str);
$str = str_replace("()", "", $str);
}
if ($str) {
return false;
}
return true;
}
隔一天又更新,最近我在看極客時間的一個專欄,《資料結構預演算法之美》,裡面有一節就提到了棧,受到啟發,我又重新優化了一下程式碼,如下
function c($str): bool {
$rightStr = ['}' => '{', ']' => '[', ')' => '('];
$leftStr = array_flip($rightStr);
/**
* 這裡使用陣列函式array_push和array_pop進行模擬出入棧操作會比 new SplStack()方式記憶體佔用更低一些
*/
$left = new SplStack();//初始化儲存符號為左的棧
$len = strlen($str);
//如果長度不是偶數直接返回false
if ($len % 2) {
return false;
}
for ($i = 0; $i < strlen($str); $i++) {
$ls = $str[$i];
if (isset($leftStr[$ls])) {
$left->push($ls);
} elseif (isset($rightStr[$ls])) {
if (!$left->isEmpty()) {
$l = $left->pop();
if ($l != $rightStr[$ls]) {
return false;
}
} else {
return false;
}
}
}
//如果左符號棧或右符號棧還有資料,就說明為false
if (!$left->isEmpty()) {
return false;
}
return true;
}