zoukankan      html  css  js  c++  java
  • 316. 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"

    链接: http://leetcode.com/problems/remove-duplicate-letters/

    题解:

    String中去除重复字符,使得去重后的String在lexicographical order里最小。这道题目主要参考了Discuss里lixx2100的解法。就是先遍历一遍String,维护一个count[26],存下来每个字符的count,之后再次遍历String,假设position = 0,每次找到字符s.charAt(i)比s.charAt(pos)小的时候,更新position,同时也更新count,当count[i] == 0的时候,这个字符就是我们要找的结果字符串里的第一个字符。之后因为其他字符的count还都 > 1,我们继续在s.substring(position + 1)的子串里递归查找第二个字符,注意要在这个子串里把第一个字符清除掉。  

    虽然time complexity是O(26n) = O(n),但实际运行起来速度比较慢,因为有很多string的操作,而我们前面也遇到过,s.substring其实已经不是O(1)的复杂度,所以会比较慢。 Discuss里另外一位rikimberley的解法就快了很多,是用数组模拟stack,还要好好体会理解。

    Time Complexity - O(n), Space Complexity - O(n)

    public class Solution {
        public String removeDuplicateLetters(String s) {
            if(s == null || s.length() == 0) {
                return s;
            }
            
            int[] count = new int[26];
            char[] res = new char[26];
            int len = s.length();
            for(int i = 0; i < s.length(); i++) {
                count[s.charAt(i) - 'a']++; 
            }
            
            int pos = 0;
            for(int i = 0; i < len; i++) {
                if(s.charAt(i) < s.charAt(pos)) {
                    pos = i;
                }
                count[s.charAt(i) - 'a']--;     
                if(count[s.charAt(i) - 'a'] == 0) {         // found first minimum char
                    break;
                }
            }
            
            String charToRemove = String.valueOf(s.charAt(pos));
            return charToRemove + removeDuplicateLetters(s.substring(pos + 1).replaceAll(charToRemove, ""));
        }
    }

    Reference:

    https://leetcode.com/discuss/73761/a-short-o-n-recursive-greedy-solution

    https://leetcode.com/discuss/74373/java-2ms-two-pointers-solution-or-stack-simulation-beats-72%25

    https://leetcode.com/discuss/73777/easy-to-understand-iterative-java-solution

    https://leetcode.com/discuss/73824/short-16ms-solution-using-stack-which-can-optimized-down-4ms

    https://leetcode.com/discuss/73806/15-ms-java-solution

    https://leetcode.com/discuss/73869/4ms-c-solution-use-return-string-as-a-stack

    https://leetcode.com/discuss/74121/some-python-solutions

    https://leetcode.com/discuss/74084/my-simple-c-o-n-solution-4ms

    https://leetcode.com/discuss/73897/8ms-o-n-java-solution

  • 相关阅读:
    JAVA并发之ReentrantLock源码(一)
    java并发之线程池
    Quine--输出程序源码的程序(java)
    【leetcode】Weekly Contest 92
    【java集合类】ArrayList和LinkedList源码分析(jdk1.8)
    【leetcode】Weekly Contest 91
    牛客2018.6模拟考编程题
    MFC 完全自定义控件
    图形学中求平面方程系数以及法向量
    std::function解决函数重载绑定
  • 原文地址:https://www.cnblogs.com/yrbbest/p/5068729.html
Copyright © 2011-2022 走看看