九章算法 | 螞蟻金服面試題:有效的括號字符串

【題目描述】

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

1.任何左括號 '('必須有一個相應的右括號')'

2.任何右括號 ')' 必須有一個相應的左括號'('

3.左括號'(' 必須在相應的右括號 ')' 之前。

4.*可以被視爲單個右括號')'或單個左括號'('或空字符串。

5.空字符串也有效。

在線評測地址:LintCode 領釦

【樣例】

        樣例 1:
	輸入:  "()"
	輸出:  true


	
樣例 2:
	輸入: "(*)"
	輸出:  true
	
	解釋:
	'*' 看作是空串.
	
樣例 3:
	輸入: "(*))"
	輸出: true
	
	解釋:
	'*' 當作'('
      

【題解】

一道簡單的思維題,考慮到星號在其中的用處就能解決.

  1. 首先進行最基礎的考慮,(在不考慮星號的情況下)我們必定會選擇位置最接近的左右括號配對,這樣避免了人爲造成的右括號前面沒有左括號匹配的慘劇。因此我們在寫程序進行處理的時候,對於每個右括號判斷前面是否有1個左括號能被他擁有,如果左括號數量不足,這個字符串必定是false,或者當整個串被匹配完之後發現有多餘的左括號,這個字符串同樣是false。
  2. 接下來考慮有星號的情況:”)”必須由位置在它之前的”(”或”*”匹配,如果”(”或者”*”數量不足導致的false是無法避免的,而如果”(“ 比”)”多,將”(”與”*”優先匹配可以減小false的可能性。舉個例子如樣例3,從左往右遍歷的時候,優先匹配”(”和”*”,遇見第一個”)”,發現沒有單獨的”(”,從”(*”的組合中拆出一個”(“與之匹配,而原先匹配中的*因爲可以等同於不存在便不予理會,接着遇到第二個”)”,拿走剛纔剩餘的”*”。綜上我們可以觀察到,”(”容易受制於”)”而將其與”*”匹配後就很靈活,不僅避免了數量太多帶來的麻煩,也能在和*匹配後再次提供自身給”)”進行匹配。而如果這樣匹配結束還有多餘的”(”則必定false
  3. 我們設l(left)爲必須被右括號匹配的左括號數量,cp(couple)爲前面左括號和星號數量。遍歷字符串,遇到左括號和星號的時候,cp++; 遇到右括號的時候cp--; 遇到星號,默認先於前面的左括號(l>0)匹配,此時(l—),遇到右括號,默認先與前面必須與右括號匹配的左括號匹配,此時(l—;cp—;)或者在支援兵中考慮(cp—) 注意cp是前方左右的左括號和星號數量,一旦cp<0即false. 匹配完發現(l>0)即多出了左括號,也爲false。剩下的情況就是true了
        public class Solution {
    /**
     * @param s: the given string
     * @return: whether this string is valid
     */
    public boolean checkValidString(String s) {
        // Write your code here
        int len=s.length();
        int l=0, cp=0;
        for (int i=0; i<len; i++) {
            if (s.charAt(i)=='(') {
                l++;
                cp++;
            } else if (s.charAt(i)=='*') {
                if (l>0) {
                    l--;
                }
                cp++;
            } else {
                if (l>0) l--;
                cp--;
                if (cp<0) return false;
            }
        }
        if (l==0)
            return true;
        else
            return false;
    }
}
      

更多語言代碼參見: 九章算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章