1. 程式人生 > >lintcode 有效括號的字串

lintcode 有效括號的字串

lintcode 有效括號的字串

描述

給定一個只包含三種類型字元的字串:’(’,’)'和 ‘*’, 編寫一個函式來檢查該字串是否有效。 我們通過以下規則定義字串的有效性:

1.任何左括號 ‘(‘必須有一個相應的右括號’)’。
2.任何右括號 ‘)’ 必須有一個相應的左括號’(’。
3.左括號’(’ 必須在相應的右括號 ‘)’ 之前。
4.*可以被視為單個右括號’)‘或單個左括號’('或空字串。
5.空字串也有效。

樣例

輸入: “()”
輸出: True

輸入: “(*)”
輸出: True

輸入: “(*))”
輸出: True

思路

根據題目的意思,形如"()()()“這樣的字串也是可以的。所以不能使用兩個指標left和right進行遍歷。這也是我一開始犯的錯誤。如果這樣的話我們可以參考堆疊判斷括號匹配的思路。這裡要注意的就是” * “可以當作” ( “也可以當作” ) ",也可以當作空字串。
從字串的開頭進行遍歷,如果 " * "被當作成 ( ,)的數量還是多於( 的,那麼肯定就無效,直接返回false,比如這種情況 " ( * ) ) ) "。因此我們需要不斷地記錄下( 和 )的數量。
這裡我們使用了兩個變數Min和Max Min記錄的是 * 被當作是 ) 時,(的數量。Max為 * 當作 ( 時, (的數量。
如果遍歷到( Min和Max都增1, )都減一, 遍歷到*時,Min–, Max++
遍歷一次之後對Max進行判斷,如果Max<0,說明)的數量過多,返回false,如果沒有返回false,說明當作左括號的*略多。如果Min小於0,要變為0,因為可能出現這樣的情況 " ( * * ) ( ) ",有效的字串是分段的。所以判斷字串是否有效,最後需要判斷Min,如果Min大於0,說明左括號數量多了,字串無效。比如這種 " ( ( ( * ) " Min的值為3。注意Min的值不可能是負的。

class Solution {
public:
    /**
     * @param s: the given string
     * @return: whether this string is valid
     */
    bool checkValidString(string &s) {
        // Write your code here
        int Min = 0, Max = 0; 
        for(int i=0; i<s.size(); i++){
            if (s[i] == '(') {
                Min++;
                Max++;   
            }
            if (s[i] == ')') {
                Min--;
                Max--;
            }
            if (s[i] == '*') {
                Min--;
                Max++;
            }
            if(Max < 0) 
               return false;
            Min = max(Min, 0);
      }
        if(Min == 0)
            return true;
        return false;
    }
};