题目
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:“abbaca” 输出:“ca” 解释:例如,在 “abbaca” 中,我们可以删除 “bb”
由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa”
可以执行重复项删除操作,所以最后的字符串为 “ca”。 提示:1 <= S.length <= 20000 S 仅由小写英文字母组成。
思路
类似于括号匹配,本题删除相邻相同元素,也是一个匹配问题,匹配相邻元素,做一个消除操作——>栈的思想
相当于对字符串进行进栈操作,每次进栈和栈顶元素对比,如果相同则则出栈顶元素,不同则入栈,最后出栈并反转一下即可
java代码:
//用Deque实现栈
class Solution {
public String removeDuplicates(String S){
ArrayDeque<Character> deque = new ArrayDeque<>();//ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
char ch;//用ch获取字符来进行每次的比较操作,出入栈操作
for(int i = 0; i < S.length(); i++){
ch = S.charAt(i);
if(deque.isEmpty() || deque.peek() != ch){//只要栈为空,或者栈顶元素比较不同,则入栈
deque.push(ch);
}else {
deque.pop();
}
}
String str = "";//创建一个字符串接收字符,将栈转化成字符串
while(!deque.isEmpty()){
str = deque.pop() + str;//注意peek是获取栈顶元素,pop是出栈操作
}
return str;
}
}
//用字符串直接作为栈,省去了将栈转化成字符串的操作
class Solution {
public String Duplicates(String S){
StringBuffer res = new StringBuffer();//res当做栈
int top = -1;//top是res的指针
for(int i = 0; i< S.length(); i++){
char c = S.charAt(i);
//如果res中有字符,并且和栈中元素相等,则将res中该字符删除,否则将该字符添加到res中
if(top >= 0 && res.charAt(top) == c){
res.deleteCharAt(top);
top--;
}else {
res.append(c);
top++;
}
}
return res.toString();
}
}