手画了个流程图,不知道你们能不能看懂呀,写的太潦草了,下次写工整些。
var removeDuplicateLetters = function(s) {
// 初始化一个空栈,用于存储最终的结果
let stack = [];
// 初始化一个计数数组,用于存储每个字母的出现次数
let count = new Array(26).fill(0);
// 初始化一个访问数组,用于记录每个字母是否已经被访问过
let visited = new Array(26).fill(false);
// 获取字符'a'的ASCII码值,用于后续计算字符在数组中的索引
let aCharCode = 'a'.charCodeAt(0);
// 遍历输入的字符串,计算每个字母的出现次数
for (let i = 0; i < s.length; i++) {
count[s.charCodeAt(i) - aCharCode]++;
}
// 再次遍历输入的字符串,对于每个字符:
for (let i = 0; i < s.length; i++) {
// 计算字符在数组中的索引
let idx = s.charCodeAt(i) - aCharCode;
// 减少计数数组中对应的计数
count[idx]--;
// 如果当前字符已经被访问过,则跳过当前字符
if (visited[idx]) continue;
// 如果栈不为空,并且当前字符小于栈顶字符,并且栈顶字符在后面还会出现,则弹出栈顶字符,并将访问数组中对应的标记设为未访问
while (stack.length > 0 && s[i] < stack[stack.length - 1] && count[stack[stack.length - 1].charCodeAt() - aCharCode] > 0) {
visited[stack[stack.length - 1].charCodeAt(0) - aCharCode] = false;
stack.pop();
}
// 将当前字符压入栈中,并将访问数组中对应的标记设为已访问
stack.push(s[i]);
visited[idx] = true;
}
// 遍历结束后,将栈中的字符连接成字符串,即为最终结果
return stack.join('');
};