前端算法 ==== 栈的好戏还要继续!| 1047. 删除字符串中的所有相邻重复项

目录

解题

思路

题外话


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

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

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

复制代码
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

解题

充分理解题意后,我们可以发现,当字符串中同时有多组相邻重复项时,我们无论是先删除哪一个,都不会影响最终的结果。因此我们可以从左向右顺次处理该字符串。

而消除一对相邻重复项可能会导致新的相邻重复项出现,如从字符串 abba 中删除 bb 会导致出现新的相邻重复项 aa 出现。因此我们需要保存当前还未被删除的字符。一种显而易见的数据结构呼之欲出:栈。我们只需要遍历该字符串,如果当前字符和栈顶字符相同,我们就贪心地将其消去,否则就将其入栈即可。

思路

本题要删除相邻相同元素,相对于20. 有效的括号来说其实也是匹配问题,20. 有效的括号 是匹配左右括号,本题是匹配相邻元素,最后都是做消除的操作。

本题也是用栈来解决的经典题目。

那么栈里应该放的是什么元素呢?

我们在删除相邻重复项的时候,其实就是要知道当前遍历的这个元素,我们在前一位是不是遍历过一样数值的元素,那么如何记录前面遍历过的元素呢?

所以就是用栈来存放,那么栈的目的,就是存放遍历过的元素,当遍历当前的这个元素的时候,去栈里看一下我们是不是遍历过相同数值的相邻元素。

然后再去做对应的消除操作。 如动画所示:

从栈中弹出剩余元素,此时是字符串ac,

复制代码
/**
 * 移除字符串中相邻字符对的函数
 * 该函数通过模拟栈操作,依次遍历字符串中的字符,每当遇到不匹配的相邻字符时,将其重新压入栈中
 * 最终,栈中剩余的字符即为去除所有相邻字符对后的结果
 *
 * @param {string} s 输入的字符串
 * @return {string} 移除相邻字符对后的字符串
 */
var removeDuplicates = function (s) {
  // 使用数组模拟栈数据结构
  const stack = [];
  // 遍历输入字符串的每个字符
  for (const x of s) {
    // 弹出栈顶元素,用于比较是否与当前字符x相同
    let prev = stack.pop();
    // 如果弹出的元素与当前字符x不同,则将弹出的元素重新压入栈,并将当前字符x也压入栈
    if (prev !== x) {
      stack.push(prev);
      stack.push(x);
    }
    // 如果相同,则不做任何操作,即实现了移除一对相邻字符的目的
  }
  // 最终栈中剩余的字符即为结果,将其转换为字符串返回
  return stack.join("");
};

// 调用示例
removeDuplicates("abbaca");

题外话

这道题目就像是我们玩过的游戏对对碰,如果相同的元素放在挨在一起就要消除。

可能我们在玩游戏的时候感觉理所当然应该消除,但程序又怎么知道该如果消除呢,特别是消除之后又有新的元素可能挨在一起。

此时游戏的后端逻辑就可以用一个栈来实现(我没有实际考察对对碰或者爱消除游戏的代码实现,仅从原理上进行推断)。

游戏开发可能使用栈结构,编程语言的一些功能实现也会使用栈结构,实现函数递归调用就需要栈,但不是每种编程语言都支持递归,例如:

递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

相信大家应该遇到过一种错误就是栈溢出,系统输出的异常是Segmentation fault(当然不是所有的Segmentation fault 都是栈溢出导致的) ,如果你使用了递归,就要想一想是不是无限递归了,那么系统调用栈就会溢出。

而且在企业项目开发中,尽量不要使用递归!在项目比较大的时候,由于参数多,全局变量等等,使用递归很容易判断不充分return的条件,非常容易无限递归(或者递归层级过深),造成栈溢出错误(这种问题还不好排查!)

相关推荐
用户8307196840822 分钟前
Java IO三大模型(BIO/NIO/AIO)超详细总结
java
sheji34162 分钟前
【开题答辩全过程】以 基于SSM的花店销售管理系统为例,包含答辩的问题和答案
java
Mr_sun.14 分钟前
Day09——入退管理-入住-2
android·java·开发语言
MAGICIAN...25 分钟前
【java-软件设计原则】
java·开发语言
Ticnix26 分钟前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人29 分钟前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
JH307331 分钟前
为什么switch不支持long
java
twl32 分钟前
OpenClaw 深度技术解析
前端
gpfyyds66633 分钟前
Python代码练习
开发语言·python
崔庆才丨静觅36 分钟前
比官方便宜一半以上!Grok API 申请及使用
前端