Remove Duplicate Letters

2020-01-19 13:18:11

问题描述

问题求解

本题是要求挑选出一个字符串的子序列,并且保证得到的子序列中能够有所有出现的字符且其字典序最小。

最容易想到的解法就是dfs了,暴力去进行检索,并生成所有的满足条件的子序列,最后从中得到字典序最小的那个。可惜使用这种算法的结果是tle。

第二个思路是用map将所有的idx保存下来,之后进行二分检索,但是这个时间复杂度也非常高。

最优的解法是使用count数组和visited数组来对字符进行统计,如果当前的字符已经出现过,那么直接pass,因为越前出现越好;如果当前的字符并没有出现,并且前面的字符比他大,而且其count大于0,那么前面的字符就可以弹出。

    public String removeDuplicateLetters(String s) {
        int[] seen = new int[26];
        char[] chs = s.toCharArray();
        int n = chs.length;
        for (char c : chs) seen[c - 'a'] += 1;
        Stack<Character> stack = new Stack<>();
        HashSet<Character> used = new HashSet<>();
        for (char c : chs) {
            seen[c - 'a'] -= 1;
            if (used.contains(c)) continue;
            while (!stack.isEmpty() && c < stack.peek() && seen[stack.peek() - 'a'] > 0) {
                char tmp = stack.pop();
                used.remove(tmp);
            }
            stack.push(c);
            used.add(c);
        }
        StringBuffer sb = new StringBuffer();
        while (!stack.isEmpty()) sb.append(stack.pop());
        return sb.reverse().toString();
    }

  

  

原文地址:https://www.cnblogs.com/hyserendipity/p/12213317.html