Leetcode--Java--316. 去除重复字母

题目描述

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

样例描述

示例 1:

输入:s = "bcabc"
输出:"abc"
示例 2:

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

思路

贪心 + 单调栈思想

  1. 用一个字符串来记录答案,每次判断答案的最后一个字符是否大于原串当前字符,如果大于并且该字符在原串后面还出现过,就可以不断删除。然后将原串当前字符加入到答案。
    在这里插入图片描述
  2. 答案字符串本质上是一个栈结果,不断在一端进行插入删除操作。
  3. 用一个哈希表记录是否在答案出现过,用另一个哈希表记录某字母最后出现的位置。
  4. 数组版和哈希表版,其实都很复杂,注意哈希表在判断是否出现过的时候,首先要判断是否存在,不然会有空指针错误。

代码

class Solution {
    
    
    public String removeDuplicateLetters(String s) {
    
    
       String res = "";
       boolean inRes[] = new boolean[26]; //是否在答案中出现过
       int lastPos[] = new int[26]; //最后出现的位置
       int n = s.length();
       for (int i = 0; i < n; i ++ ) {
    
    
           lastPos[s.charAt(i) - 'a'] = i;
       }
       for (int i = 0; i < n; i ++ ) {
    
    
           char c = s.charAt(i);
           if (inRes[c - 'a']) continue;
           while (!"".equals(res) && res.charAt(res.length() - 1) > c && lastPos[res.charAt(res.length() - 1) - 'a'] > i) {
    
    
               //标记为没出现过
              inRes[res.charAt(res.length() - 1) - 'a'] = false;
              //去掉最后一位字符
              res = res.substring(0, res.length() - 1);
           }
           //加入新的字符,并且标记为出现过
           res += c;
           inRes[c - 'a'] = true;
       }
       return res;
    }
}

哈希表版本

class Solution {
    
    
    public String removeDuplicateLetters(String s) {
    
    
        String res = "";
        Map<Character, Boolean> inRes = new HashMap<>(); // 是否在结果中出现
        Map<Character, Integer> last = new HashMap<>(); // 最后一次出现的位置
        for (int i = 0; i < s.length(); i++) last.put(s.charAt(i), i);

        for (int i = 0; i < s.length(); i++) {
    
    
            char cur = s.charAt(i);
             //要判断是否存在key,存在的前提下才能get,不然会空指针报错
            if (inRes.containsKey(cur) && inRes.get(cur)) continue; // 已经出现过,则跳过

            // 若当前字符比上一个字符小,且结果中字符在后面出现过。则循环处理将比当前字符大的字符都替换掉
            while (res.length() > 0 && cur < res.charAt(res.length() - 1)  && last.get(res.charAt(res.length() - 1)) > i  ) {
    
    
                inRes.put(res.charAt(res.length() - 1), false);
                res = res.substring(0, res.length() - 1);
            }

            res = res + cur;
            inRes.put(cur, true);
        }

        return res;
    }
}


猜你喜欢

转载自blog.csdn.net/Sherlock_Obama/article/details/121741216