本篇使用已經實現好的棧來解一個簡單題:
給定一個只包括 '(',')','{','}','[',']' 的字串 s ,判斷字串是否有效。
有效字串需滿足:
左括號必須用相同型別的右括號閉合。
左括號必須以正確的順序閉合。
輸入:s = "{[]}"輸出:true
輸入:s = "([)]"輸出:false
1 <= s.length <= 10^4s 僅由括號 '()[]{}' 組成
思路分析:
s的長度最長可達到10^4,使用陣列實現的棧已經不合適,我們就使用基於單鏈表實現的棧。這是基於已經封裝好的棧的實現來說的。如果我們使用陣列,可以先求出字串的實際長度,然後再定義棧陣列的長度即可。
對給定的僅由括號'()[]{}'組成的字串s進行遍歷,遍歷到的每一個左括號,在後續的遍歷中,有一個相同型別的右括號將其閉合。為了保證左括號必須以正確的順序閉合,後遇到的左括號要先閉,將這個左括號放入棧頂。
當遍歷遇到一個右括號時,他需要一個相同型別的左括號將其閉合。我們將棧頂的左括號取出,判斷是否為相同型別的括號。如果不是相同型別,或者棧中沒有左括號,字串S就是無效的,返回false。
過程分析:
注意到有效字串的長度一定為偶數,因此如果字串的長度為奇數,我們可以直接返回 ,省去後續的遍歷判斷過程。
if(strlen(s) % 2 != 0)return ret;
在遍歷結束後,如果棧中沒有左括號,說明我們將字串 s 中的所有左括號閉合,返回 \text{True}True,否則返回 \text{False}False。
return IsStackEmpty(stack) ? ret : false;
遇到一個右括號時,他需要一個相同型別的左括號將其閉合。我們將棧頂的左括號取出,判斷是否為相同型別的括號。如果不是相同型別,或者棧中沒有左括號,字串S就是無效的,返回false。
按照這個邏輯我們寫出瞭如下程式碼,可以看出只是三個括號型別不同,程式碼其餘部分相同,這種程式碼是應該去重的。
//第一個括號if(s[i] == '}'){ StackPop(stack, &data); if(data != '{') { return false; } else { i++; } }//第二個括號if(s[i] == ']'){ StackPop(stack, &data); if(data != '[') { return false; } else { i++; } }//第三個括號if(s[i] == ')'){ StackPop(stack, &data); if(data != ')') { return false; } else { i++; } }
去重程式碼如下:
//把不同括號型別用同一個函式來獲取char mach(char c){ if(c == '}')return '{'; if(c == ')')return '('; if(c == ']')return '['; return false;}//這樣上邊的程式碼就可以化簡為如下形式if(mach(s[i])){ StackPop(stack, &data); if(data != mach(s[i++])) { return false; } }
為了保證左括號必須以正確的順序閉合,後遇到的左括號要先閉,將這個左括號放入棧頂。
if((s[i] == '{') || (s[i] == '(') || (s[i] == '[')) { StackPush(stack, s[i++]); }
完整程式碼如下:
最新評論