leetcode316去除重复字符串

204 阅读1分钟

手画了个流程图,不知道你们能不能看懂呀,写的太潦草了,下次写工整些。

ea719396da7d7d29da4ff0a448b84ae.jpg

078f6596f43f95e9c538aba8787deda.jpg

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('');

};