本文最后更新于:2022年9月5日 晚上
给出由小写字母组成的字符串 S
,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
| 输入:"abbaca" 输出:"ca" 解释: 例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
|
提示:
1 <= S.length <= 20000
S
仅由小写英文字母组成。
Solution
- 可以把字符串顺序放到一个栈中,然后如果相同的话 栈就弹出,这样最后栈里剩下的元素都是相邻不相同的元素了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: string removeDuplicates(string S) { if (S.size() == 0) return S; stack<char> stack; for (char c : S) { if (!stack.empty() && stack.top() == c) { stack.pop(); } else { stack.push(c); } } string ss = ""; while (!stack.empty()) { ss += stack.top(); stack.pop(); } reverse(ss.begin(), ss.end()); return ss; } };
|
注:
| - ss = stack.top() + ss; + ss += stack.top(); + reverse(ss.begin(), ss.end());
|
第一行代码得出的结果即为输出顺序,但是这种字符串拼接性能消耗大,执行超时。
- 利用字符串模拟栈,参考 @carlsun-2
- 空间复杂度 O(1)
| class Solution { public: string removeDuplicates(string S) { if (S.size() == 0) return S; string res;
for (char c : S) { if (res.empty() || res.back() != c) { res.push_back(c); } else { res.pop_back(); } } return res; } };
|
java
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) { Deque<Character> stack = new ArrayDeque<>(); for (int i = 0; i < s.length(); ++i) { char ch = s.charAt(i); if (stack.isEmpty() || stack.peek() != ch) { stack.push(ch); } else { stack.pop(); } } String res = ""; while (!stack.isEmpty()) { res = stack.pop() + res; } return res; } }
|
| class Solution { public String removeDuplicates(String s) { char[] chars = s.toCharArray(); int top = -1; for (int i = 0; i < s.length(); ++i) { if (top == -1 || chars[top] != chars[i]) { chars[++top] = chars[i]; } else { top--; } } return String.valueOf(chars, 0, top + 1); } }
|