返回

剑指offer算法题解:有效括号

闲谈

问题

给定一个只包括 '(', ')', '{', '}', '[', ']' 的字符串 s,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。

例如:

输入:s = "()"
输出:true
输入:s = "()[]{}"
输出:true
输入:s = "(]"
输出:false

解题思路

判断括号是否有效,可以采用栈数据结构。栈是一种遵循后进先出(LIFO)原则的数据结构,可以用来存储和管理左括号。当遇到左括号时,将其压入栈中;当遇到右括号时,从栈中弹出左括号进行匹配。如果所有括号都能正确匹配,则字符串有效;否则,字符串无效。

具体步骤如下:

  1. 初始化一个栈。
  2. 遍历字符串 s 中的每个字符。
  3. 如果当前字符是左括号,将其压入栈中。
  4. 如果当前字符是右括号,则从栈中弹出左括号进行匹配。
  5. 如果栈为空,则字符串有效。
  6. 如果栈不为空,则字符串无效。

代码实现

def is_valid(s):
  """
  判断字符串是否有效。

  Args:
    s: 输入字符串。

  Returns:
    布尔值,表示字符串是否有效。
  """

  # 初始化栈
  stack = []

  # 遍历字符串中的每个字符
  for char in s:
    # 如果当前字符是左括号,将其压入栈中
    if char in ['(', '{', '[']:
      stack.append(char)
    # 如果当前字符是右括号,则从栈中弹出左括号进行匹配
    elif char in [')', '}', ']']:
      # 如果栈为空,则字符串无效
      if not stack:
        return False
      # 从栈中弹出左括号进行匹配
      left_char = stack.pop()
      # 如果匹配失败,则字符串无效
      if not is_match(left_char, char):
        return False

  # 如果栈为空,则字符串有效
  return not stack


def is_match(left_char, right_char):
  """
  判断两个括号是否匹配。

  Args:
    left_char: 左括号。
    right_char: 右括号。

  Returns:
    布尔值,表示两个括号是否匹配。
  """

  return (left_char == '(' and right_char == ')') or \
         (left_char == '{' and right_char == '}') or \
         (left_char == '[' and right_char == ']')


# 测试代码
print(is_valid("()"))  # True
print(is_valid("()[]{}"))  # True
print(is_valid("(]"))  # False
print(is_valid("([)]"))  # False

时间复杂度和空间复杂度分析

  • 时间复杂度:O(n),其中 n 是字符串 s 的长度。算法需要遍历字符串中的每个字符,因此时间复杂度为 O(n)。
  • 空间复杂度:O(n),其中 n 是字符串 s 的长度。算法需要使用栈来存储左括号,因此空间复杂度为 O(n)。