【题目描述】
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
【示例】
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
【思路1】字符串数组
1、直接使用字符串数组
2、判断数组内的最后一个字符和当前字符是否相同
3、如果相同,删除数组最后一个字符 继续遍历下一个字符
4、时间复杂度O(n)
5、空间复杂度O(n)
Swift代码实现
func removeDuplicates1(_ S: String) -> String {
var res = String()
for c in S {
if res.isEmpty || res.last != c {
res.append(c)
} else {
res.popLast()
}
}
return res
}
【思路2】栈
1、比较当前字符和栈顶字符是否相同
2、如果相同,栈顶元素pop,继续遍历下一个字符,知道字符串遍历完成
3、倒序返回栈内字符
4、时间复杂度O(n)
5、空间复杂度O(n)
Swift代码实现
栈-数组实现
struct Stack<T> {
fileprivate var arr = [T]()
mutating func pop() -> T {
return self.arr.removeLast()
}
mutating func push(_ num:T) {
self.arr.append(num)
}
func isEmpty() -> Bool {
return self.arr.isEmpty
}
func peek() -> T? {
return self.arr.last
}
func size() -> Int {
return self.arr.count
}
}
func removeDuplicates(_ S: String) -> String {
var res = String()
var stack = Stack<Character>.init()
for c in S {
if stack.isEmpty() {
stack.push(c)
continue
}
if stack.peek()! == c {
stack.pop()
continue
}
stack.push(c)
}
var tmpStack = Stack<Character>.init()
while !stack.isEmpty() {
tmpStack.push(stack.pop())
}
while tmpStack.size() > 0 {
res.append(tmpStack.pop())
}
return res
}