题目:
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
思路一:
和消消乐很相似,两个相邻字符一样消掉。
由于都是小写,总共会有26组字符串出现会被消除。'aa'到'zz',存储到set中。
当消除前的字符串长度!=消除后的字符串长度,说明还有可消除的。
代码如下:
public String removeDuplicates1(String S) {
// 准备替换字符set
// 'a'= 97 , 'z'=122
Set<String> set = new HashSet<String>();
for (int i = 97; i <= 122; i++) {
char c = (char) i;
set.add("" + c + c);
}
int preLen = 0;// 替换前字符串长度
while (preLen != S.length()) {//判断换前长度是否和当前长度相等
preLen = S.length();
for (String s : set) {
S = S.replace(s, "");
}
}
return S;
}
思路二:
由于是相邻相同会消除,使用栈来存放每个字符。
创建栈,入栈前先比较栈顶字符和即将入栈字符是否一致。
一致则移除栈顶字符,不一致则添加进去。
需要注意栈为空的情况。
代码如下:
public boolean backspaceCompare(String S, String T) {
Stack<Character> stackS = new Stack<Character>();
Stack<Character> stackT = new Stack<Character>();
int len = S.length() > T.length() ? S.length() : T.length();
for (int i = 0; i < len; i++) {
if (i < S.length()) {
char s = S.charAt(i);
if ('#' == s) {
if (!stackS.isEmpty())
stackS.pop();
} else {
stackS.push(s);
}
}
if (i < T.length()) {
char t = T.charAt(i);
if ('#' == t) {
if (!stackT.isEmpty())
stackT.pop();
} else {
stackT.push(t);
}
}
}
return stackS.equals(stackT);
}
-------------------------------小白学算法