面对编程难题时,栈与队列为何大显身手?
2023-11-07 10:07:36
栈和队列是两种重要的数据结构,在计算机科学中有着广泛的应用。栈是一种遵循后进先出(LIFO)原则的数据结构,这意味着最后添加的元素将首先被删除。队列是一种遵循先进先出(FIFO)原则的数据结构,这意味着最早添加的元素将首先被删除。
栈和队列都可以在编程中发挥重要作用。例如,栈可以用于存储函数调用时的局部变量,队列可以用于存储等待处理的任务。此外,栈和队列还可以用于解决各种算法问题。
在本文中,我们将以一个编程案例来演示栈和队列的应用。这个案例是判断一个给定的括号字符串是否有效。给定一个只包含 '('、')'、'{'、'}'、'['、']' 的字符串 s,判断字符串是否有效。有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
例如,以下字符串是有效的:
"()"
"()[]{}"
"{[]}"
以下字符串是非有效的:
"([)]"
"{[]}"
"(){}}{"
为了解决这个问题,我们可以使用栈来存储左括号。当我们遇到一个左括号时,我们将它压入栈中。当我们遇到一个右括号时,我们将它与栈顶的左括号进行比较。如果它们匹配,则将它们弹出栈。否则,我们知道字符串是非有效的。
以下是使用栈来判断括号字符串是否有效的代码:
def is_valid(s):
stack = []
for char in s:
if char in ['(', '{', '[']:
stack.append(char)
elif char in [')', '}', ']']:
if not stack:
return False
top = stack.pop()
if not ((top == '(' and char == ')') or (top == '{' and char == '}') or (top == '[' and char == ']')):
return False
return not stack
这个代码首先创建一个空栈。然后,它遍历字符串中的每个字符。如果字符是左括号,则将它压入栈中。如果字符是右括号,则将它与栈顶的左括号进行比较。如果它们匹配,则将它们弹出栈。否则,我们知道字符串是非有效的。最后,如果栈为空,则字符串是有效的。否则,字符串是非有效的。
队列也可以用于解决各种算法问题。例如,队列可以用于广度优先搜索。广度优先搜索是一种遍历图的算法,它从根节点开始,逐层遍历图的节点。在每层中,算法将所有节点加入队列。然后,算法从队列中取出一个节点,并访问它的所有相邻节点。这些相邻节点随后被加入队列。该过程重复,直到所有节点都被访问。
以下是使用队列来进行广度优先搜索的代码:
def bfs(graph, root):
queue = [root]
visited = set()
while queue:
node = queue.pop(0)
if node not in visited:
visited.add(node)
for neighbor in graph[node]:
queue.append(neighbor)
return visited
这个代码首先创建一个队列,并将根节点加入队列。然后,它创建一个集合来存储已访问的节点。接下来,它从队列中取出一个节点,并访问它的所有相邻节点。这些相邻节点随后被加入队列。该过程重复,直到所有节点都被访问。最后,函数返回已访问的节点集合。
栈和队列都是重要的数据结构,它们在计算机科学中有着广泛的应用。栈可以用于存储函数调用时的局部变量,队列可以用于存储等待处理的任务。此外,栈和队列还可以用于解决各种算法问题。