一、题目描述:
给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
****示例 1:
输入:s = "bcabc"
输出:"abc"
二、思路分析:
- 先扫描一次字符串记录,字符出现的次数
- 然后使用单调栈,保证栈中的字符按字典序排序,这时又分为两种情况(如果是已经出现在栈中的字符,则直接跳过就好,因为要保证字符串中的字符不重复):
- 1.如果字符的次数大于1,那么可以把它 pop 出去,后面再 push 到栈里,刚好符合字典序的要求(仔细思考一下,若果后面还会出现这个字符,且当前扫描到的字符已经小于栈顶的元素了,那么结果序列必不包含当前栈顶的字符)
- 2.如果字符出现的次数等于1,前面也说了栈中不会存在重复的元素,那么就不能把它 pop 出去
三、AC 代码:
/**
* @param {string} s
* @return {string}
*/
var removeDuplicateLetters = function (s) {
const counterMap = {}
for (let i = 0; i < s.length; i++) {
if (!counterMap[s[i]]) {
counterMap[s[i]] = 1
} else {
counterMap[s[i]]++
}
}
const inStackMap = {}
const stack = []
for (let i = 0; i < s.length; i++) {
counterMap[s[i]]--
if (inStackMap[s[i]]) {
continue
}
while (s[i] < stack[stack.length - 1]) {
if (counterMap[stack[stack.length-1]] === 0) {
break
}
let popEle = stack.pop()
inStackMap[popEle] = false
}
stack.push(s[i])
inStackMap[s[i]] = true
}
return stack.join("")
};
四、总结:
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情