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 1:

    Input: "bcabc"
    Output: "abc"
    

    Example 2:

    Input: "cbacdcbc"
    Output: "acdb"

    intuition: The leftmost letter in our solution will be the smallest letter such that the suffix from that letter contains every other. This is because we know that the solution must have one copy of every letter, and we know that the solution will have the lexicographically smallest leftmost character possible. If there are multiple smallest letters, then we pick the leftmost one simply because it gives us more options. We can always eliminate more letters later on, so the optimal solution will always remain in our search space.

    reference: https://leetcode.com/problems/remove-duplicate-letters/solution/

    M1:  Greedy - solving letter by letter

    We use idea number one from the intuition. In each iteration, we determine leftmost letter in our solution. This will be the smallest character such that its suffix contains at least one copy of every character in the string. We determine the rest our answer by recursively calling the function on the suffix we generate from the original string (leftmost letter is removed).

    time = O(n), space = O(n)

    class Solution {
        public String removeDuplicateLetters(String s) {
            int[] cnt = new int[26];
            for(char c : s.toCharArray()) {
                cnt[c - 'a']++;
            }
            
            int pos = 0;    // the index of the smallest character before iteration ends
            for(int i = 0; i < s.length(); i++) {
                if(s.charAt(i) < s.charAt(pos)) {
                    pos = i;
                }
                if(--cnt[s.charAt(i) - 'a'] == 0) {
                    break;
                }
            }
            // answer is the leftmost letter plus the recursive call on the rest of the string
            return s.length() == 0 ? "" : s.charAt(pos) + removeDuplicateLetters(s.substring(pos + 1).replaceAll("" + s.charAt(pos), ""));
        }
    }

    M2: 

    class Solution {
        public String removeDuplicateLetters(String s) {
            StringBuilder sb = new StringBuilder();
            int[] cnt = new int[26];
            boolean[] seen = new boolean[26];
            
            char[] chs = s.toCharArray();
            for(char c : chs) {
                cnt[c - 'a']++;
            }
            
            for(char c : chs) {
                cnt[c - 'a']--;
                if(seen[c - 'a']) {
                    continue;
                }
                // when the last character in sb is larger than c and appears more than once, delete it from sb
                while(sb.length() > 0 && sb.charAt(sb.length() - 1) > c && cnt[sb.charAt(sb.length() - 1) - 'a'] > 0) {
                    seen[sb.charAt(sb.length() - 1) - 'a'] = false;
                    sb.deleteCharAt(sb.length() - 1);
                }
                sb.append(c);
                seen[c - 'a'] = true;
            }
            return sb.toString();
        }
    }
  • 相关阅读:
    OpenGL, Net 2005, error C2381: 'exit' : redefinition; __declspec(noreturn) differs
    24点游戏
    一个3*3的格子,给定n>=10, 将[1,n]中的数填入方格中,使得相邻方格的数的和为质数
    最大子矩阵问题 PKU 1050
    12年9月12日
    再谈MSDN Library For Visual Studio 2010
    漫谈.NET开发中的字符串编码
    《.NET 4.0网络开发入门之旅》4:与Socket的第一次“约会”
    “.NET 4.0 网络开发入门之旅系列文章”—— IP 知多少?(下)
    C#之int挑战Java之Integer
  • 原文地址:https://www.cnblogs.com/fatttcat/p/11399494.html
Copyright © 2011-2022 走看看