LeetCode刷题-删除字符串中的所有相邻重复项

前言说明

算法学习,日常刷题记录。

题目连接

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

题目内容

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

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

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

示例:

输入:"abbaca"

输出:"ca"

解释:

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

提示:

1 <= S.length <= 20000

S仅由小写英文字母组成。

分析过程

我们很容易就能想到用栈的方法来解决,而且相关标签也提示用栈。

当前元素和栈顶元素不同时,入栈。

当前元素和栈顶元素相同时,不入栈,并且出栈,这时就把重复项删除了。

所以如下代码:

class Solution {
    public String removeDuplicates(String s) {
        // 定义栈,保存不相邻重复的字符
        Stack stack = new Stack<>();

        // 遍历字符串s的字符
        for (int i = 0; i < s.length(); ++i) {
            if (stack.size() > 0) {
                // 若栈不为空,判断栈的顶部元素是否和当前字符相等
                if (stack.peek() == s.charAt(i)) {
                    // 若栈的顶部元素和当前字符相等,出栈,删掉了两个相邻重复的元素
                    stack.pop();
                } else {
                    // 若栈的顶部元素和当前字符不相等,字符入栈
                    stack.push(s.charAt(i));
                }
            } else {
                // 若栈为空,直接字符入栈
                stack.push(s.charAt(i));
            }
        }

        // 定义字符串集合
        StringBuilder sb = new StringBuilder();

        // 遍历栈的元素,从头到尾遍历
        for (Character character : stack) {
            // 把栈的元素保存到字符串集合
            sb.append(character);
        }
        
        // 字符串集合转为字符串,返回结果
        return sb.toString();
    }
}

但是提交后运行时间如下:

运行结果

执行用时28ms,时间击败39.22%的用户,内存消耗39.1MB,空间击败41.99%的用户。

运行时间和运行空间都不理想,但是我们看题目的提示就是说用栈来解决的啊,为什么运行结果这么不理想的?

后来我逛了一下评论区才发现,原来小丑是我,在LeetCode的讨论区有一个这样的评论,如下:

image.png

题目提示使用栈,你就真的乖乖地定义一个栈吗?

其实StringBuilder本身就可以模拟出栈的功能,何必多此一举去先定义一个栈,再遍历栈把栈的内容写入StringBuilder里呢?直接使用StringBuilder来保存元素就可以了。

解答代码

所以更节省时间和空间的代码如下:

class Solution {
    public String removeDuplicates(String s) {
        // 定义字符串集合
        StringBuilder sb = new StringBuilder();

        // 定义字符串集合最外元素的下标
        int top = -1;

        // 遍历字符串s的字符
        for (int i = 0; i < s.length(); ++i) {
            if (top >= 0 && sb.charAt(top) == s.charAt(i)) {
                // 若字符串集合的最外元素和当前字符相等,删除最外元素,并且字符不保存进字符串集合
                sb.deleteCharAt(top);
                // 字符串集合最外元素的下标减1
                --top;
            } else {
                // 若字符串集合的最外元素和当前字符不相等,字符保存进字符串集合
                sb.append(s.charAt(i));
                // 字符串集合最外元素的下标加1
                ++top;
            }
        }
        
        // 字符串集合转为字符串,返回结果
        return sb.toString();
    }
}

提交结果

执行用时13ms,时间击败77.58%的用户,内存消耗39MB,空间击败67.16%的用户。

运行结果

原文链接

原文链接:删除字符串中的所有相邻重复项

你可能感兴趣的:(LeetCode刷题-删除字符串中的所有相邻重复项)