Problem: AB5 点击消除
题目描述
描述
牛牛拿到了一个字符串。
他每次“点击”,可以把字符串中相邻两个相同字母消除,例如,字符串"abbc"点击后可以生成"ac"。
但相同而不相邻、不相同的相邻字母都是不可以被消除的。
牛牛想把字符串变得尽可能短。他想知道,当他点击了足够多次之后,字符串的最终形态是什么?
输入描述:
一个字符串,仅由小写字母组成。(字符串长度不大于300000)
输出描述:
一个字符串,为“点击消除”后的最终形态。若最终的字符串为空串,则输出0。
示例1
输入:
abbc
输出:
ac
解题思路
这道题目要求我们通过不断消除字符串中相邻的相同字母,直到无法再进行消除为止,最终得到最短的字符串。这与经典的“消除相邻相同字符”问题非常相似,可以使用栈(Stack)这种数据结构来高效地解决。
关键点:
- 栈的使用:栈是一种后进先出(LIFO)的数据结构,非常适合处理这种需要检查相邻元素的问题。我们可以遍历字符串的每个字符,利用栈来跟踪当前未被消除的字符。
- 消除规则:对于当前字符,如果它与栈顶的字符相同,则弹出栈顶字符(表示消除这对相邻相同字符);否则,将当前字符压入栈中。
- 最终结果:遍历完整个字符串后,栈中剩下的字符就是无法再消除的字符,将它们按顺序拼接起来就是最终结果。如果栈为空,则返回
0
。
算法流程
- 初始化栈:创建一个空栈
stack
用于存储字符。- 遍历字符串: 对于字符串中的每个字符
char
: 检查栈是否非空且栈顶字符是否等于char
: 如果是,弹出栈顶字符(消除相邻相同字符)。 如果不是,将char
压入栈中。- 生成结果: - 将栈中的字符按顺序拼接成字符串
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);
}
})();
复杂度
- 时间复杂度:
添加时间复杂度, 示例:
- 空间复杂度:
添加空间复杂度, 示例: