前言
“代码随想录”刷题记录。总结笔记均会放在“算法刷题-代码随想录”该专栏下,以下为原文的链接。
代码随想录此题链接
题目
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:“abbaca”
输出:“ca”
解释:
例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。
提示:
1 <= S.length <= 20000
S 仅由小写英文字母组成。
1.栈匹配
思路(定义变量)
- 申请一个栈对象stack记录相邻的元素是否相同。
2. 本题思路分析:
- 遍历字符串,将元素与栈顶元素进行比较,如果入栈的元素与栈顶元素相同则说明:这两个相邻的元素相同。
- 则把栈顶元素移出栈并把这个元素压入栈
- 如果入栈的元素与栈顶元素不同,则说明相邻的元素不同,把当前的元素压入栈。
3. 算法实现
- 代码:
JAVA
public String removeDuplicates(String s) {
LinkedList<Character> stack = new LinkedList<>();
for(char c : s.toCharArray()){
if(stack.isEmpty() || stack.peek() != c){
stack.push(c);
continue;
}else{
stack.pop();//这里不用考虑上一个之前还有可匹配字符的情况,有匹配的已经被消除了
}
}
StringBuilder sb = new StringBuilder();
for(char c : stack){
sb.append(c);
}
sb.reverse();
return sb.toString();
}
C++
#include<stack>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
string removeDuplicates(string s) {
stack<int> st;
for(char c : s){
if(st.empty() || st.top() != c){
st.push(c);
}else{
st.pop();
}
}
string result;
while(st.size()){
result += st.top();
st.pop();
}
reverse(result.begin(),result.end());
return result;
}
4. pop函数的算法复杂度
- 时间复杂度:O(n)
- 空间复杂度:O(n)
5. 算法坑点
- 在遇到相同时,只要将栈顶的元素pop即可,不需要考虑内部还要重复的情况,因为题目中说的是重复的元素两两消除。所有的元素都会被遍历,如果之前有重复的元素,则已经被去除过了。
if(stack.isEmpty() || stack.peek() != c){
stack.push(c);
continue;
}else{
stack.pop();//这里不用考虑上一个之前还有可匹配字符的情况,有匹配的已经被消除了
}