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

题目描述

这是 LeetCode 上的 1047. 删除字符串中的所有相邻重复项 ,难度为 简单

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

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

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

示例:

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

提示:

  • 1 <= S.length <= 20000
  • S 仅由小写英文字母组成。

(自带) 栈解法

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public String removeDuplicates(String s) {
char[] cs = s.toCharArray();
Deque<Character> d = new ArrayDeque<>();
for (char c : cs) {
if (!d.isEmpty() && d.peekLast().equals(c)) {
d.pollLast();
} else {
d.addLast(c);
}
}
StringBuilder sb = new StringBuilder();
while (!d.isEmpty()) sb.append(d.pollLast());
sb.reverse();
return sb.toString();
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

(数组模拟) 栈解法

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public String removeDuplicates(String s) {
char[] cs = s.toCharArray();
char[] d = new char[s.length()];
int hh = 0, tt = -1;
for (char c : cs) {
if (hh <= tt && d[tt] == c) {
tt--;
} else {
d[++tt] = c;
}
}
StringBuilder sb = new StringBuilder();
while (hh <= tt) sb.append(d[tt--]);
sb.reverse();
return sb.toString();
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

(自带) 双端队列解法

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public String removeDuplicates(String s) {
char[] cs = s.toCharArray();
Deque<Character> d = new ArrayDeque<>();
for (char c : cs) {
if (!d.isEmpty() && d.peekLast().equals(c)) {
d.pollLast();
} else {
d.addLast(c);
}
}
StringBuilder sb = new StringBuilder();
while (!d.isEmpty()) sb.append(d.pollFirst());
return sb.toString();
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

(数组模拟) 双端队列解法

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public String removeDuplicates(String s) {
char[] cs = s.toCharArray();
char[] d = new char[s.length()];
int hh = 0, tt = -1;
for (char c : cs) {
if (hh <= tt && d[tt] == c) {
tt--;
} else {
d[++tt] = c;
}
}
StringBuilder sb = new StringBuilder();
while (hh <= tt) sb.append(d[hh++]);
return sb.toString();
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

纯数组解法

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public String removeDuplicates(String s) {
char[] cs = s.toCharArray();
char[] d = new char[s.length()];
int hh = 0, tt = -1;
for (char c : cs) {
if (hh <= tt && d[tt] == c) {
tt--;
} else {
d[++tt] = c;
}
}
return new String(d, 0, tt + 1);
}
}
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(n)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.1047 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。