在刷题中学习的知识与见解 | 豆包MarsCode AI 刷题

51 阅读3分钟

问题描述

小M拿到了一个由小写字母组成的字符串 s。她发现可以进行一种操作:选择两个相邻且相同的字母并删除它们。她可以在 s 上反复进行此操作,直到无法再删除任何字母。 请返回最终处理完所有重复项删除操作后的字符串。可以保证返回的答案是唯一的。


测试样例

样例1:

输入:s = "abbaca"
输出:'ca'

样例2:

输入:s = "azxxzy"
输出:'ay'

样例3:

输入:s = "a"
输出:'a'

结果展示

def solution(s: str) -> str:  
stack = []  # 初始化栈  
for char in s:
    if stack and stack[-1] == char:  
        stack.pop()  # 删除相邻重复的字符  
    else:  
        stack.append(char)  # 压入当前字符  
return ''.join(stack)  # 将栈中的字符合并为字符串
if __name__ == '__main__':  
print(solution(s="abbaca") == 'ca')  
print(solution(s="azxxzy") == 'ay')  
print(solution(s="a") == 'a')  
`

题目解析

题目要求
给定一个仅由小写字母组成的字符串 s,通过反复执行以下操作:找到两个相邻且相同的字符并删除它们,直到字符串中再无可删除的字符为止。返回最终剩余的字符串。

核心思路

  1. 借助栈:栈是一种后进先出的数据结构,非常适合处理这一类相邻字符配对消除的操作。

  2. 逐个遍历字符串

    • 如果当前字符和栈顶字符相同,则删除栈顶元素(模拟“消除”)。
    • 如果不同,将当前字符压入栈。
  3. 最终结果:栈中的元素就是处理后的字符串,从栈底到栈顶依次输出即可。

图解
以输入 s = "abbaca" 为例:

当前字符栈状态(处理后)操作描述
'a'['a']第一个字符入栈
'b'['a', 'b']不同字符入栈
'b'['a']栈顶 'b' 相同,出栈
'a'[]栈顶 'a' 相同,出栈
'c'['c']不同字符入栈
'a'['c', 'a']不同字符入栈

最终栈内容为 ['c', 'a'],输出结果为 'ca'

代码详解

def solution(s: str) -> str:
    # 初始化栈,用于存放字符
    stack = []
    # 遍历字符串
    for char in s:
        # 栈非空且当前字符与栈顶相同时,消除栈顶
        if stack and stack[-1] == char:
            stack.pop()
        else:
            # 否则,将当前字符压入栈
            stack.append(char)
    # 将栈中的字符合并为最终字符串返回
    return ''.join(stack)

# 测试用例
if __name__ == '__main__':
    print(solution("abbaca") == 'ca')  # 测试样例1
    print(solution("azxxzy") == 'ay')  # 测试样例2
    print(solution("a") == 'a')        # 测试样例3

代码详解

  1. 栈初始化stack = [] 用于模拟字符串的“消除”过程。
  2. 遍历字符串:逐字符判断是否与栈顶相同,决定是“出栈”还是“入栈”。
  3. 合并栈元素:最后通过 ''.join(stack) 将栈中的字符拼接为字符串。

知识总结

  1. 栈的应用场景

    • 栈常用于需要“回溯”或“配对”的场景。例如括号匹配问题、消除问题等。
    • 特点:后进先出,模拟类似递归和消除的过程。
  2. 解题经验

    • 遇到**“连续消除”类型问题时,可以优先考虑用栈**来处理。
    • 栈的常用操作:push(压入)、pop(弹出)、peek(查看栈顶元素)、isEmpty(是否为空)。
  3. 学习建议

    • 熟悉栈的操作,理解其在递归、深度优先搜索中的作用。
    • 刷题过程中,尽量用图解来帮助理解问题的本质。
  4. 其他注意点

    • 注意边界情况:如空字符串、只有一个字符的字符串等。
    • 熟练使用 Python 的 list 数据结构来模拟栈。

对入门同学的学习建议

  1. 理解核心思路:不要急着写代码,先用纸笔画图模拟一遍问题,理解栈如何帮助解决“相邻字符消除”的问题,这样可以更深入的了解题目要求和更好的理解。
  2. 多动手实践:将不同输入输出的场景逐一测试,从而加深理解。
  3. 总结模式:类似的“消除”问题都可以归类到一个“解题框架”中。
  4. 提升难度:尝试将题目扩展,比如对更复杂的规则或字符串进行操作。