栈 | 豆包MarsCode AI刷题

164 阅读5分钟

栈(Stack) 是一种常见的数据结构,它具有“后进先出”(Last-In-First-Out,LIFO)的特性。栈可以看做是一种特殊的线性表,只能在栈顶进行插入和删除操作。栈顶是允许操作的,而栈底是固定的。

栈的基本操作包括:入栈(Push)、出栈(Pop)、取栈顶元素(Top)和判空(IsEmpty)等。

常见的实现方式包括数组实现和链表实现。Python中可以直接使用列表(List)来实现栈的功能。

  • stack = []:创建一个空栈。
  • stack.append(element):将元素压入栈中。
  • element = stack.pop():弹出栈顶元素。
  • element = stack[-1]:查看栈顶元素。
  • if stack:检查栈是否为空。

477 相邻重复字母删除问题

问题描述

小M拿到了一个由小写字母组成的字符串 s。她发现可以进行一种操作:选择两个相邻且相同的字母并删除它们。她可以在 s 上反复进行此操作,直到无法再删除任何字母。

请返回最终处理完所有重复项删除操作后的字符串。可以保证返回的答案是唯一的。

解题思路

  1. 初始化

    • 创建一个空栈 stack 用于存储字符。
  2. 遍历字符串

    • 对于每个字符 char

      • 如果栈不为空且当前字符 char 与栈顶字符相同,则弹出栈顶字符(即删除相邻重复字符)。
      • 否则,将当前字符 char 压入栈中。
  3. 返回结果

    • 栈中剩余的字符即为最终处理完所有重复项删除操作后的字符串。将栈中的字符按顺序拼接成字符串并返回。
def solution(s: str) -> str:
    stack = []
    for char in s:
        if stack and char == stack[-1]:
            stack.pop()
        else:
            stack.append(char)
    #将栈中的字符按顺序拼接成字符串并返回
    return ''.join(stack)

484 股票价格上涨天数计算

问题描述

小C是一名股票交易员,最近他关注某只股票的价格波动。给定该股票连续N天的价格列表 stockPrices,你需要为小C生成一个新列表,每个位置的值表示从那天起至少需要等待多少天才能看到价格上涨。如果没有上涨的情况,则对应位置的值为0。

例如,对于股票价格列表 [33, 34, 14, 12, 16],从第一天价格 33 开始,价格上涨发生在第二天价格 34,所以输出 1。若某天之后不再有价格上涨,则输出 0。

解题思路

  1. 初始化

    • 创建一个与 stockPrices 长度相同的列表 result,初始值为0。
    • 创建一个栈 stack,用于存储价格的下标(天数)。
  2. 遍历价格列表

    • 对于每个价格 stockPrices[i]

      • 如果栈不为空且出现价格上涨(即当前价格 stockPrices[i] 大于栈顶元素对应的价格 stockPrices[stack[-1]]),则进入循环:

        • 弹出栈顶元素 index
        • 计算等待天数(即当前下标 i 与栈顶元素下标 index 的差值 i - index),并更新给 result[index]
      • 将当前下标 i 压入栈中。

  3. 返回结果

    • 遍历结束后,返回 result 列表。
def solution(N: int, stockPrices: list) -> list:

    result = [0]*N        # 初始化结果列表
    stack = []            # 创建一个栈来存储价格的下标
    for i in range(N):
        while stack and stockPrices[i] > stockPrices[stack[-1]]:
            # 弹出栈顶元素,并计算当前下标与栈顶元素下标的差值
            index = stack.pop()
            result[index] = i - index
        stack.append(i)   # 将当前下标压入栈中
    return result

427 括号补全问题

问题描述

小R有一个括号字符串 s,他想知道这个字符串是否是有效的。一个括号字符串如果满足以下条件之一,则是有效的:

  1. 它是一个空字符串;
  2. 它可以写成两个有效字符串的连接形式,即 AB
  3. 它可以写成 (A) 的形式,其中 A 是有效字符串。

在每次操作中,小R可以在字符串的任意位置插入一个括号。你需要帮小R计算出,最少需要插入多少个括号才能使括号字符串 s 有效。

例如:当 s = "())" 时,小R需要插入一个左括号使字符串有效,结果为 1

解题思路

  1. 初始化

    • 创建一个空栈 stack 用于存储未匹配的括号。
  2. 遍历字符串

    • 逐个字符遍历输入字符串 s
    • 如果当前字符是左括号 '(',将其压入栈中。
    • 如果当前字符是右括号 ')',检查栈顶元素:
      • 如果栈不为空且栈顶元素是左括号 '(',则弹出栈顶元素(表示匹配成功)。
      • 否则,将当前右括号压入栈中。
  3. 返回结果

    • 遍历结束后,栈中剩余的元素数量即为需要插入的最少括号数。
def solution(s: str) -> int:
    stack = []
    for char in s:
        if char == '(':                      #左括号,入栈
            stack.append(char)
        elif stack and stack[-1] == '(':     #右括号,检查栈顶元素是否匹配,匹配成功则弹出栈顶元素
            stack.pop()
        else:
            stack.append(char)
    return len(stack)

258 括号字符串最短长度计算

问题描述

小F拿到了一串只包含'('和')'的括号字符串。她可以进行以下两种操作:
1.将相邻的一对括号'()'合并为'('
2.将相邻的一对括号'()'合并为')'
小F想知道,经过若干次操作后,能够将这个括号字符串的长度缩短到最小,最短的长度是多少?

解题思路

  1. 初始化

    • 创建一个空栈 stack 用于存储未匹配的括号。
    • 将输入字符串 s 转换为双端队列 a,以便从左到右遍历、插入字符串。
  2. 遍历字符串

    • 从双端队列 a 中逐个弹出字符 char
    • 如果 char 是 ')'或'|' 并且栈顶元素是 '('或'|',则说明找到了一对可以匹配的括号,将栈顶元素弹出(即匹配成功),将'|'加入队列左侧(即一对括号合并为一个万能括号)
    • 否则,将当前字符 char 压入栈中。
  3. 返回结果

    • 栈的长度即为简化后的字符串的最短长度。
from collections import deque
def solution(s: str) -> int:
    # 初始化栈
    stack = []
    a = deque(s)
    # 遍历字符串
    while a:
        char = a.popleft()
        if stack and  char in  '|)' and stack[-1] in "(|":
            stack.pop()
            a.appendleft('|')
        else:
            stack.append(char)

    # 栈的长度就是最短长度
    return len(stack)