返回

掌握栈和队列基础,轻松攻克有效括号(Valid Parentheses)!

后端

栈与队列:数据结构的基石

数据结构在计算机科学中扮演着至关重要的角色,它们为组织和管理数据提供了框架。其中,栈和队列是两大基础数据结构,它们在各种编程领域有着广泛的应用。

栈:后进先出

栈是一种后进先出(LIFO)的数据结构,就像一摞盘子。每次你从栈中添加或移除元素,都必须操作栈顶的元素。这种特性使得栈非常适合函数调用、递归和表达式求值等场景。

队列:先进先出

与栈不同,队列是一种先进先出(FIFO)的数据结构,就像一个队列。每次你从队列中添加元素时,新元素会被插入队尾。而每次移除元素时,队首的元素会被弹出。队列常用于消息传递、任务调度和进程间通信等场景。

有效括号:栈的经典应用

在编程面试中,一道经典的题目就是有效括号。给定一个字符串,其中只包含括号字符,你需要判断这个字符串是否有效。一个字符串被称为有效,当且仅当其中的括号都是成对出现的,并且每个左括号都与一个右括号相匹配。

栈是解决有效括号问题的理想数据结构。我们可以逐个扫描字符串中的字符,并利用栈对每个字符进行处理:

  • 左括号:将左括号压入栈中。
  • 右括号:如果栈顶元素是与该右括号匹配的左括号,则将栈顶元素弹出。否则,返回false。

当扫描完整个字符串后,如果栈为空,则说明字符串中的所有括号都是成对出现的,返回true。否则,返回false。

代码实现:C++、Java、Python

bool isValid(string s) {
  stack<char> stk;
  for (char c : s) {
    if (c == '(' || c == '{' || c == '[') {
      stk.push(c);
    } else {
      if (stk.empty() || stk.top() != getMatch(c)) {
        return false;
      }
      stk.pop();
    }
  }
  return stk.empty();
}

char getMatch(char c) {
  switch (c) {
    case ')': return '(';
    case '}': return '{';
    case ']': return '[';
  }
  return ' ';
}
public boolean isValid(String s) {
  Stack<Character> stack = new Stack<>();
  for (char c : s.toCharArray()) {
    if (c == '(' || c == '{' || c == '[') {
      stack.push(c);
    } else {
      if (stack.isEmpty() || stack.pop() != getMatch(c)) {
        return false;
      }
    }
  }
  return stack.isEmpty();
}

private char getMatch(char c) {
  switch (c) {
    case ')': return '(';
    case '}': return '{';
    case ']': return '[';
  }
  return ' ';
}
def is_valid(s):
  stack = []
  for char in s:
    if char in '([{':
      stack.append(char)
    else:
      if not stack or char != match(stack.pop()):
        return False
  return not stack

def match(char):
  return {
    ')': '(',
    '}': '{',
    ']': '[',
  }[char]

结语

通过本文,我们深入了解了栈和队列的基础知识,并以一道经典的编程题目——有效括号——为例,掌握了栈和队列的使用技巧。希望这些知识能够帮助你解决更多编程难题,并在编程面试中脱颖而出。

常见问题解答

1. 栈和队列有什么区别?

栈是后进先出(LIFO)的数据结构,就像一摞盘子,而队列是先进先出(FIFO)的数据结构,就像一个队列。

2. 什么是有效括号?

有效括号是指一个字符串中的括号都是成对出现的,并且每个左括号都与一个右括号相匹配。

3. 如何使用栈解决有效括号问题?

我们可以逐个扫描字符串中的字符,并利用栈对每个字符进行处理:左括号压入栈中,右括号弹出与之匹配的左括号。

4. 栈和队列在实际应用中有哪些场景?

栈用于函数调用、递归、表达式求值等场景,而队列用于消息传递、任务调度、进程间通信等场景。

5. 如何在不同编程语言中实现栈和队列?

在不同的编程语言中,栈和队列的实现方式可能有所不同,但基本的原理是一致的。