题目描述
1047. 删除字符串中的所有相邻重复项
给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。
在 S 上反复执行重复项删除操作,直到无法继续删除。
在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。
示例:
输入:"abbaca"
输出:"ca"
解释:
例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。
提示:
1 <= S.length <= 20000
S 仅由小写英文字母组成。
链接:leetcode-cn.com/problems/re…
算法思路
模拟
根据题目要求,我们每枚举一个数,就判断它和前面仍存在的数比较,若相等,则删除这两个数。
具体代码的话,我们可以用一个hash表来记录被删去了的数,遍历时,与前面最近的一个未被删除的数进行比较。最后再遍历一遍字符串,将仍然存在的字符记录下来即可。
代码如下:
/**
* @param {string} S
* @return {string}
*/
var removeDuplicates = function(s) {
const n = s.length
const hash = {}
for(let i = 1; i < n; ++ i) {
let j = i - 1
while(j >= 0 && hash[j]) -- j
if(s[i] == s[j])
hash[i] = hash[j] = true
}
let ans = ""
for(let i = 0; i < n; ++ i)
if(!hash[i])
ans += s[i]
return ans;
};
时间复杂度:O(n ^ 2)
栈
根据上面的思路,我们可以发现这类似于一个"消消乐"的游戏,如果你经常看我的文章,你会发现每次题目中具有"消消乐"的性质,都可以使用栈的先入先出特性来解决。
实现流程是这样的:我们维护一个栈存储当前未被删除的字符,然后看下个字符是否与栈顶字符相等,若相等则应该将下个字符与当前栈顶的字符都除去,我们弹出栈顶字符即可。
代码如下:
/**
* @param {string} S
* @return {string}
*/
Array.prototype.top = function() {
return this[this.length - 1]
}
var removeDuplicates = function(s) {
const n = s.length
const stk = []
for(let i = 0; i < n; ++ i) {
if(stk.length && stk.top() === s[i]) stk.pop()
else stk.push(s[i])
}
return stk.join("")
};
时间复杂度:O(n) 空间复杂度:O(n)
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!