LeetCode刷题笔记 字节每日打卡 去除重复字母

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。

示例 1:

输入:s = "bcabc"
输出:"abc"
输入:s = "cbacdcbc"
输出:"acdb"

参考: 力扣


需要用到栈的数据结构

vis记录栈内是否有该字母,num记录字母最后出现的下标

遍历所有字母

  • 如果栈内已有该字母跳过不加入
  • 比较栈顶字母,如果栈顶字母比现在字母大且栈顶字母后续还有(最后位置比当前位置靠后)说明可以删去当前栈顶字母(因为后续可以加入)
  • 加入当前字母

注意:加入删除字母的时候应该两个数组全部删除。

class Solution {
    public String removeDuplicateLetters(String s) {
        boolean[] vis = new boolean[26];// 表明栈中是否有该元素
        int[] num = new int[26];// 记录每个字母最后出现的下标
        char[] cs = s.toCharArray();
        int l = cs.length;
        for (int i = 0; i < l; i++) {
            num[cs[i] - 'a'] = i;
        }
        // 用StringBuffer当栈,也可用deque
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < l; i++) {
            // 遍历s
            char ch = cs[i];
            // 栈中有该字母直接跳过不需要计算
            if(vis[ch-'a']){
                continue;
            }
            // 栈顶最后的字符比当前字符大 且 后续有栈顶最后的字符
            // 此时就可以去除当前栈顶最后的字符
            // 去除注意需要把vis和sb都去除
            while (sb.length() > 0 && sb.charAt(sb.length() - 1) > ch && num[sb.charAt(sb.length() - 1) - 'a'] > i) {
                    vis[sb.charAt(sb.length() - 1) - 'a'] = false;
                    sb.deleteCharAt(sb.length() - 1);
            }
            // 加入当前字符
            vis[ch - 'a'] = true;
            sb.append(ch);
        }
        // 返回sb即可
        return sb.toString();
    }
}
上一篇:SpringCloud简单入门示例


下一篇:Leetcode-D44-数组-48. 旋转图像&54. 螺旋矩阵(明天复习)