zoukankan      html  css  js  c++  java
  • [leetcode] Remove Duplicate Letters

    题目:

    Given a string which contains only lowercase letters, remove duplicate letters so that every letter appear once and only once. You must make sure your result is the smallest in lexicographical order among all possible results.
    
    Example:
    Given "bcabc"
    Return "abc"
    
    Given "cbacdcbc"
    Return "acdb"

    分析:通过观察每个字母下标的规律,以"cbacdcbc"为例,

    第一步,计算下标(countIndex):

    a  => 2,  
    
    b  => 1, 6
    
    c  => 0, 3, 5, 7
    
    d  => 4

    第二步,寻找符合条件的字母(findLetter):

    如果一个字母的第一个下标小于其后每个字母最后一个下标,则该字母符合条件。比如 a 中的 2 小于 b 的 6,c 的 7,d 的 4,则 a 中的2符合条件。

    第三步,删除前面的下标(removeIndex):

    不防设第二步中符合条件的字母为X,则删除X下标之前的所有下标,并删除X。比如X为a,X下标为2,则删除 b 中的 1,c 中的 0,并把 a 删除。

    重复第二步,第三步,直到集合为空。

    以 "cbacdcbc" 为例:

    b  => 6
    
    c  => 3, 5, 7
    
    d  => 4
    b  => 6
    
    
    
    d  => 4

    上述变换解释:虽然 6 < 7,但 6 却 > 4, 故 b 不符合,而 c 中的 3 小于其后的 4,故 c 符合。 

    b  => 6

    故最后生成 a -> c -> d -> b,即 acdb.

    代码如下:

        public String removeDuplicateLetters(String s) {
            StringBuilder res = new StringBuilder();
            HashMap<Character, ArrayList<Integer>> hm = new HashMap<Character, ArrayList<Integer>>();
            ArrayList<Character> reference = new ArrayList<Character>();
            countIndex(s, hm, reference);
            Collections.sort(reference);
            while (!reference.isEmpty()) {
                int lettIndex = findLetter(s, res, hm, reference);
                removeIndex(lettIndex, hm, reference);
            }
            return res.toString();
        }
        
        private void countIndex(String s, HashMap<Character, ArrayList<Integer>> hm, ArrayList<Character> reference) {
            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                if (! hm.containsKey(ch)) {
                    ArrayList<Integer> tmp = new ArrayList<Integer>();
                    tmp.add(i);
                    hm.put(ch, tmp);
                    reference.add(ch);
                } else {
                    hm.get(ch).add(i);
                }
            }
        }
        
        private int findLetter(String s, StringBuilder res, HashMap<Character, ArrayList<Integer>> hm, ArrayList<Character> reference) {
            int m = 0;
            for (int i = 0; i < reference.size(); i++) {
                m = hm.get(reference.get(i)).get(0);
                int j = i+1;
                for (; j < reference.size(); j++) {
                    ArrayList<Integer> tmp = hm.get(reference.get(j));
                    if (m > tmp.get(tmp.size()-1)) {
                        break;
                    }
                }
                if (j == reference.size()) {
                    res.append(reference.get(i));
                    reference.remove(i);
                    break;
                }
            }
            return m;
        }
        
        private void removeIndex(int lett, HashMap<Character, ArrayList<Integer>> hm, ArrayList<Character> reference) {
            for (int i = 0; i < reference.size(); i++) {
                ArrayList<Integer> tmp = hm.get(reference.get(i));
                while (!tmp.isEmpty() && tmp.get(0) < lett) {
                    tmp.remove(0);
                }
            }
        }
  • 相关阅读:
    react给input元素中文输入的时候自动转成字符串bug
    charles代理
    es6和es5函数参数和arguments的差别
    Uncaught InvalidStateError: Failed to set the 'value' property on 'HTMLInputElement': This input element accepts a filename, which may only be programmatically set to the empty string.
    Node 开发概述
    对Flutter路由管理库Fluro的封装
    Flutter 切换标签显示对应的列表+Provide状态管理实例
    Flutter 商城实例 分类列表
    Flutter 入口页面及底部导航栏实例制作
    Flutter 建立项目和编写入口文件
  • 原文地址:https://www.cnblogs.com/lasclocker/p/5037254.html
Copyright © 2011-2022 走看看