栈,你给我玩这个字符消消乐!

简介: 栈,你给我玩这个字符消消乐!

大家好呀,我是帅蛋。


今天来做字符串消消乐,当然不是那个消消乐,是它的弟中弟中弟版,只需要相邻是重复的消掉就好了。


话不多说,直接肝题!

640.png

   LeetCode 1047:删除字符串中的所有相邻重复项



题意


小写字母组成字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。


示例


输入:abbaca

输出:ca


提示


答案保证唯一


1 <= S.length <= 20000

S 仅由小写英文字母组成


题目解析


水题,难度简单。


匹配到相邻的两个元素是相同的就消除你看有没有眼熟,像不像是括号匹配那道题。


呃,如果你不知道括号匹配那道题,看下面链接咧,我写过


栈,你告诉我这个括号配不配!


这种类型的题都算是匹配问题,只要是匹配问题,大家记住,在没有思路的时候,都可以考虑用栈碰一碰


既然看透了这道题的本质,那做法也就呼之欲出了。


维护一个栈,从左到右依次扫描字符串,让当前字符和栈顶元素比较:


  • 如果相同,证明当前两个元素相邻且相同或者由于之前删除了相同元素导致间接相邻且相同,此时栈顶元素出栈,当前字符不入栈。
  • 如果不同,则当前元素入栈。


如此反复,直至扫描结束,栈里剩下啥字符就是啥字符。


需要注意的是,删除两个相邻且相同的字符可能会产生新的相邻且相同的字符


图解


假设字符串 S = abbaca


首先初始化栈

# 初始化栈
stack = []


根据“题目解析”中说的,如果当前元素与栈顶元素不同,则当前元素入栈。


所以第 1 步,当前元素为 a,栈为空,所以元素 a 入栈。

640.png


第 2 步,当前元素为 b,此时栈顶元素为 a,两者不相等,所以元素 b 入栈。

640.png

接下来第 3 步,当前元素为 b,栈顶元素为 b,两者相等,栈顶元素出栈。

640.png

for char in s: 
    if stack and stack[-1] == char:
        stack.pop()


之后第 4 步,当前元素为 a,栈顶元素为 a,这就是由于删除两个相邻且相同的字符,产生了新的相邻且相同的字符。

640.png


最后两步没有相同的,直接入栈,输出栈内元素即可。


在这提醒一下编程语言直接用“栈”这个结构的,输出的时候要反转下字符串


640.png


因为从头到尾只遍历字符串 S 一次,所以时间复杂度为 O(n)


在这个过程中,维护了一个额外的栈,所以本解法空间复杂度为 O(n)


代码实现


Python 代码实现

class Solution:
    def removeDuplicates(self, s: str) -> str:
        # 初始化栈
        stack = []
        for char in s:
            # 如果"栈不为空"且"栈顶元素和当前元素相同"则栈顶元素出栈
            if stack and stack[-1] == char:
                stack.pop()
            # 否则当前元素进栈
            else:
                stack.append(char)
        # 栈内元素拼接成一个字符串
        return ''.join(stack)


Java 代码实现


此处直接拿字符串当栈,省去了栈要转为字符串的操作。

class Solution {
    public String removeDuplicates(String s) {
        // 将 res 当做栈
        StringBuffer res = new StringBuffer();
        // top为 res 的长度
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
            if (top >= 0 && res.charAt(top) == c) {
                res.deleteCharAt(top);
                top--;
            // 否则,将该字符 入栈,同时top++
            } else {
                res.append(c);
                top++;
            }
        }
        return res.toString();
    }
}


好啦,图解这道题目长长的题到这里就结束啦。


这道题就很能说明问题,其实就是换汤不换药,穿上个马甲也不能装乌龟。


大家在做题的时候还是得仔细琢磨,不能过去了就是过去了


有问题,扔到留言区。


看到这都是真爱,记得点赞在看么么哒呀。


我是帅蛋,我们下次见!



相关文章
|
20天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
103 9
|
11天前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
19 1
|
13天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
16天前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
18天前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
46 4
|
1月前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
31 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
|
23天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
1月前
初步认识栈和队列
初步认识栈和队列
60 10
|
1月前
数据结构(栈与列队)
数据结构(栈与列队)
20 1
|
1月前
|
算法
数据结构与算法二:栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式
这篇文章讲解了栈的基本概念及其应用,并详细介绍了中缀表达式转换为后缀表达式的算法和实现步骤。
48 3

热门文章

最新文章