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 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);
    }
}

你可能感兴趣的:(LeetCode,leetcode)