LeetCode 1047. Remove All Adjacent Duplicates In String

You are given a string s consisting of lowercase English letters. A duplicate removal consists of choosing two adjacent and equal letters and removing them.

We repeatedly make duplicate removals on s until we no longer can.

Return the final string after all such duplicate removals have been made. It can be proven that the answer is unique.

Example 1:

Input: s = "abbaca"
Output: "ca"
Explanation: 
For example, in "abbaca" we could remove "bb" since the letters are adjacent and equal, and this is the only possible move.  The result of this move is that the string is "aaca", of which only "aa" is possible, so the final string is "ca".

Example 2:

Input: s = "azxxzy"
Output: "ay"

Constraints:

  • 1 <= s.length <= 105
  • s consists of lowercase English letters.

这题要求把string里所有相邻的相同的字母都移除以后的string。

乍一眼没看出来,但是仔细一看其实相当于就是把一个个字符往string里加,如果新加的和最后一个字符相等就把最后一个remove,本质上也就是operation类型的经典stack题。用stack解很简单:

class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> stack = new ArrayDeque<>();
        for (char c : s.toCharArray()) {
            if (!stack.isEmpty() && stack.peek() == c) {
                stack.pop();
            } else {
                stack.push(c);
            }
        }
        StringBuilder sb = new StringBuilder();
        for (char c : stack) {
            sb.append(c);
        }
        return sb.reverse().toString();
    }
}

然后看解答,原来可以不用额外的stack,直接用StringBuilder的deleteCharAt(index)来实现。

class Solution {
    public String removeDuplicates(String s) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (sb.length() > 0 && c == sb.charAt(sb.length() - 1)) {
                sb.deleteCharAt(sb.length() - 1);
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

另外还有双指针的解法,其实也是kind of 2 pointers:一个指针lastIndex指向不含dupliate的最后一个字符,另一个指针i在整个char array里顺序扫描。这里这个char array相当于就是动态更新,变相存储了新的结果。如果当前扫描到的字符和lastIndex的字符一样,那么就要让lastIndex--,否则就直接lastIndex++并把新的index的字符设为当前字符。最后return的时候只需要return这一部分的的长度,于是需要在转换的时候specify range。

class Solution {
    public String removeDuplicates(String s) {
        char[] array = s.toCharArray();
        int lastIndex = -1;  // last index of non duplicate char
        for (char c : array) {
            if (lastIndex >= 0 && c == array[lastIndex]) {
                lastIndex--;
            } else {
                lastIndex++;
                array[lastIndex] = c;
            }
        }
        return new String(array, 0, lastIndex + 1);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值