1. 程式人生 > 實用技巧 >[LeetCode] 20. Valid Parentheses(有效的括號)

[LeetCode] 20. Valid Parentheses(有效的括號)

Description

Given a string s containing just the characters (, ), {, }, [ and ], determine if the input string is valid.

給一個包含三種括號((){}[])的字串 s,判斷其是否是有效的。

An input string is valid if:

當輸入的字串滿足以下條件時,判定為有效:

  1. Open brackets must be closed by the same type of brackets.

    左括號必須有匹配的右括號關閉

  2. Open brackets must be closed in the correct order.

    左括號必須按正確的順序被關閉

Examples

Example 1

Input: s = "()"
Output: true

Example 2

Input: s = "()[]{}"
Output: true

Example 3

Input: s = "(]"
Output: false

Example 4

Input: s = "([)]"
Output: false

Example 5

Input: s = "{[]}"
Output: true

Constraints

  • 1 <= s.length <= 10^4

  • s consists of parentheses only '()[]{}'.

Hints

  1. An interesting property about a valid parenthesis expression is that a sub-expression of a valid expression should also be a valid expression. (Not every sub-expression) e.g.

    一個有關合法括號表示式的一個有趣的屬性是:一個合法的括號表示式,其子表示式也會是一個合法的表示式(當然,不是所有的子表示式都符合),例如:

    { { } [ ] [ [ [ ] ] ] }  is VALID expression
              [ [ [ ] ] ]    is VALID sub-expression
      { } [ ]                is VALID sub-expression
    

    Can we exploit this structure somehow?

    能否利用這種結構?

  2. What if whenever we encounter a matching pair of parenthesis in the expression, we simply remove it from the expression? This would keep on shortening the expression. e.g.

    當無論什麼時候,只要在表示式內找到一對合法的括號,我們就移除它們,會發生什麼呢?這有利於簡化表示式,例如:

    { { ( { } ) } }
          |_|
    
    { { (      ) } }
        |______|
    
    { {          } }
      |__________|
    
    {                }
    |________________|
    
    VALID EXPRESSION!
    
  3. The stack data structure can come in handy here in representing this recursive structure of the problem. We can't really process this from the inside out because we don't have an idea about the overall structure. But, the stack can help up process this recursively i.e. from outside to inwards.

    這個資料結構可以很容易地描述問題中的結構。當總體結構無法把握時,處理過程無法從裡向外進行。但,棧可以幫助我們從外向裡地解決它。

Solution

利用棧這個資料結構,從題目的描述中可以發現,合法的括號對具有棧的性質:左括號是入棧操作,右括號是出棧操作。出入棧的順序一致即合法,程式碼如下:

import java.util.*

class Solution {
    fun isValid(s: String): Boolean {
        val stack = ArrayDeque<Char>()

        for (c in s) {
            when (c) {
                '(', '{', '[' -> stack.push(c)
                ')', '}', ']' -> if (!matches(c, stack)) return false
                else -> return false
            }
        }

        return stack.isEmpty()
    }

    private fun matches(c: Char, stack: Deque<Char>): Boolean {
        if (stack.isEmpty()) {
            return false
        }
        val map = mapOf(
            '(' to ')', '[' to ']', '{' to '}'
        )
        return map[stack.pop()]?:'\u0000' == c
    }
}