AB5 点击消除

19 阅读2分钟

Problem: AB5 点击消除

题目描述

描述

牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?

输入描述:

一个字符串,仅由小写字母组成。(字符串长度不大于300000)

输出描述:

一个字符串,为“点击消除”后的最终形态。若最终的字符串为空串,则输出0。

示例1

输入:abbc

输出:ac

解题思路

这道题目要求我们通过不断消除字符串中相邻的相同字母,直到无法再进行消除为止,最终得到最短的字符串。这与经典的“消除相邻相同字符”问题非常相似,可以使用栈(Stack)这种数据结构来高效地解决。

关键点:
  1. 栈的使用:栈是一种后进先出(LIFO)的数据结构,非常适合处理这种需要检查相邻元素的问题。我们可以遍历字符串的每个字符,利用栈来跟踪当前未被消除的字符。
  2. 消除规则:对于当前字符,如果它与栈顶的字符相同,则弹出栈顶字符(表示消除这对相邻相同字符);否则,将当前字符压入栈中。
  3. 最终结果:遍历完整个字符串后,栈中剩下的字符就是无法再消除的字符,将它们按顺序拼接起来就是最终结果。如果栈为空,则返回 0

算法流程

  1. 初始化栈:创建一个空栈 stack 用于存储字符。
  2. 遍历字符串: 对于字符串中的每个字符 char: 检查栈是否非空且栈顶字符是否等于 char: 如果是,弹出栈顶字符(消除相邻相同字符)。 如果不是,将 char 压入栈中。
  3. 生成结果: - 将栈中的字符按顺序拼接成字符串 result。 - 如果 result 为空字符串,返回 0;否则返回 result

代码

const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
    // Write your code here
    while ((line = await readline())) {
        let str = line.trim();
        const stack = [];

        for (const char of str) {
            if (stack.length > 0 && stack[stack.length - 1] === char) {
                stack.pop();
            } else {
                stack.push(char);
            }
        }

        const result = stack.join('');
        console.log(result === '' ? 0 : result);
    }
})();

复杂度

  • 时间复杂度:

添加时间复杂度, 示例: O(N)O(N)

  • 空间复杂度:

添加空间复杂度, 示例: O(N)O(N)