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

我的解

class Solution {
    public String removeDuplicates(String s) {
        Stack<Character> stack = new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            if (!stack.empty() && stack.peek() == s.charAt(i)) {
                stack.pop();
            } else {
                stack.push(s.charAt(i));
            }
        }
        int n = stack.size();
        char[] ch = new char[n];
        while (!stack.empty()) {
            ch[--n] = stack.pop();
        }
        return new String(ch);
    }
}

我的解分为两部分,第一部分是入栈匹配,第二个部分是出栈转为结果字符串。但是运行时间很长,有可以改进的部分。

String str = "";
        while (!stack.empty()) {
            str = stack.pop() + str;
        }
        return str;

改变第二部分,但是时间性能并没有提升

class Solution {
    public String removeDuplicates(String s) {
        StringBuilder res = new StringBuilder();
        int inx = -1;
        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            if (inx < 0 || res.charAt(inx) != ch) {
                res.append(ch);
                inx++;
            } else {
                res.deleteCharAt(inx--);
            }
        }
        return res.toString();
    }
}

本质上,String是一个不可变字符串,每一次对String操作的过程都是重新创建一个String字符串的过程。使用StringBuilder这个可变字符串对象大大提高了时间性能。

class Solution {
    public String removeDuplicates(String s) {
        char[] ch = s.toCharArray();
        int slow = 0;
        int fast = 0;
        // 原地操作 slow指针指向新字符串尾部的下一个字符
        while (fast < s.length()) {
            ch[slow] = ch[fast];
            // slow指针指向新字符串尾部
            if (slow > 0 && ch[slow] == ch[slow - 1]) {
                slow--;
                //为什么要--,因为新字符串应该退出一个字符
            } else {
                slow++;
            }
            fast++;
        }
        return new String(ch, 0, slow);
    }
}

原地操作,双指针发,之前也用过这种思路,快指针操作String s,慢指针操作新字符串。这里需要注意的是慢指针指向的是新字符串的下一个位置,在循环一开始,先把这个位置尝试填上字符,如果可以消掉,那慢指针后退一步。
String初始化可以指定字符数组的索引String(ch, 0, slow),[0,slow).

你可能感兴趣的:(数据结构,算法)