leetcode
leetcode 1151 ~ 1200
删除字符串中的所有相邻重复项 II

删除字符串中的所有相邻重复项 II

难度:

标签:

题目描述

代码结果

运行时间: 62 ms, 内存: 20.5 MB


/*
 * 思路:
 * 使用栈结构来存储字符和其计数。
 * 遍历字符串,利用Java 8的Stream API来处理。
 * 如果栈顶元素与当前字符相同,则计数加一。
 * 如果计数达到k,则从栈中移除该元素。
 * 最后,利用StringBuilder构建最终的字符串结果。
 */

import java.util.*;
import java.util.stream.Collectors;

class Solution {
    public String removeDuplicates(String s, int k) {
        Stack<Pair> stack = new Stack<>();
        s.chars().mapToObj(c -> (char) c).forEach(c -> {
            if (!stack.isEmpty() && stack.peek().character == c) {
                stack.peek().count++;
                if (stack.peek().count == k) {
                    stack.pop();
                }
            } else {
                stack.push(new Pair(c, 1));
            }
        });
        return stack.stream()
                .map(p -> String.valueOf(p.character).repeat(p.count))
                .collect(Collectors.joining());
    }

    class Pair {
        char character;
        int count;
        Pair(char character, int count) {
            this.character = character;
            this.count = count;
        }
    }
}

解释

方法:

此题解采用栈的数据结构来解决问题。对于每一个字符,若栈为空或栈顶元素与当前字符不同,则将此字符和计数1作为一个列表推入栈中。如果栈顶元素与当前字符相同,则增加栈顶元素的计数。当栈顶元素的计数达到k时,将其从栈中弹出,这模拟了删除k个相同字符的操作。最后,栈中剩余的元素代表了最终的字符串,其中每个元素包括字符及其剩余次数,将它们拼接起来得到最终结果。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在解题思路中,使用栈来处理字符串中的重复字符时,为什么选择栈而不是其他数据结构如队列或链表?
栈是一种后进先出(LIFO)的数据结构,它非常适合处理与最近相关的元素。在本题中,我们需要关注最近添加的字符和其出现次数,以便能够在达到重复次数k时迅速移除它们。使用栈可以让我们轻松地访问和操作这些最近的字符及其计数信息。而如果使用队列(先进先出),则需要额外的操作来访问队尾的元素,这会增加实现的复杂性。使用链表虽然可以高效地在任何位置插入或删除,但其在内存中通常不如栈或队列连续,且节点的额外指针会增加内存消耗。因此,栈在此类问题中提供了既简单又高效的解决方案。
🦆
当栈顶元素的计数达到k时,我们移除这个元素,但如果栈顶下面的元素与当前处理的字符相同,这种情况如何处理?
在实现中,每次字符入栈前,都会检查栈顶元素。如果栈顶元素被移除后(因为其计数达到k),则再次检查新的栈顶元素是否与当前处理的字符相同。如果相同,我们继续增加该栈顶元素的计数。如果不同或栈为空,则将当前字符以新的元素形式推入栈中。因此,通过每次都重新检查栈顶元素,可以确保连续相同的字符被正确地计数和处理,无论它们是原本就在栈中,还是由于中间元素的移除而暴露出来。
🦆
解题思路中提到,最坏情况下每个字符可能多次进出栈,能否给出一个具体的示例说明这种情况如何发生?
考虑字符串 'aabbaabb' 和 k = 2 的情况。初始时,字符 'a' 入栈,计数变为1,再次 'a' 入栈,计数变为2,然后因达到k,这对'a'被移除。接下来,两个 'b' 重复上述过程,也被移除。此时,栈为空,然后再次遇到 'a' 和 'b',重复之前的入栈和移除过程。在这种情况下,每个字符都进栈两次并被移除。这种反复进出栈的情况发生在字符的重复次数恰好与k相等,且这种模式多次出现的场景中。

相关问题