Q
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:”abbaca”
输出:”ca”
解释:
例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。
A
递归
分解问题
1.单次删除重复项操作
去除第一个遇到的重复项操作
1 2 3 4 5 6 7 8 9 10 11 12
| String str = "abbaca"; char[] chars = str.toCharArray();
char[] temp = new char[chars.length-2]; for (int i = 0; i <chars.length-1 ; i++) { if(chars[i]==chars[i+1]){ for (int j = i; j < chars.length-2 ; j++) { chars[j] = chars[j+2]; System.arraycopy(chars,0,temp,0,chars.length-2); } } }
|
2.递归重复操作
设置baseCase,进行递归调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public static char[] deleteRepeat(char[] chars){ if(chars.length == 0 || chars.length == 1){ return chars; } char[] temp = new char[chars.length-2]; for (int i = 0; i <chars.length-1; i++) { if(chars[i]==chars[i+1]){ for (int j = i; j < chars.length-2 ; j++) { chars[j] = chars[j+2]; } System.arraycopy(chars,0,temp,0,chars.length-2); return deleteRepeat(temp); } } return chars; }
|
栈
由于条件为删除连续且重复的字符,故可以模拟栈结构来一次遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution { public String removeDuplicates(String S) { StringBuffer stack = new StringBuffer(); int top = -1; for (int i = 0; i < S.length(); ++i) { char ch = S.charAt(i); if (top >= 0 && stack.charAt(top) == ch) { stack.deleteCharAt(top); --top; } else { stack.append(ch); ++top; } } return stack.toString(); } }
|
一次遍历
- 时间复杂度
O(n) - 空间复杂度
O(n) 或 O(1),取决于使用的语言提供的字符串类是否提供了类似「入栈」和「出栈」的接口。注意返回值不计入空间复杂度。