1. 程式人生 > 其它 >有效括號-棧 leetcode題庫第二十題

有效括號-棧 leetcode題庫第二十題

技術標籤:資料結構leetcode

來自力扣題庫第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;
}

在這裡插入圖片描述