[leetcode-316]Remove Duplicate Letters

来源:互联网 发布:怎么下ps软件 编辑:程序博客网 时间:2024/05/17 04:21

该题思路有两种,一种是将string当做stack处理,另一种是贪婪算法

class Solution {public:    string removeDuplicateLetters(string s) {        bool inRes[26] = {false};        int counts[26] = {0};                for (auto ch : s) counts[ch - 'a']++;                string res = "";                for (auto ch : s) {            counts[ch - 'a']--;                        if (res.empty()) {                res.push_back(ch);                inRes[ch - 'a'] = true;                continue;            }                        if (inRes[ch - 'a']) {                continue;            }                        while (ch < res.back() && !res.empty() && counts[res.back() - 'a'] > 0) {                inRes[res.back() - 'a'] = false;                res.pop_back();            }                        res.push_back(ch);                        inRes[ch - 'a'] = true;        }                return res;    }};


Given the string s, the greedy choice (i.e., the leftmost letter in the answer) is the smallest s[i], s.t. the suffix s[i .. ] contains all the unique letters. (Note that, when there are more than one smallest s[i]'s, we choose the leftmost one. Why? Simply consider the example: "abcacb".)

After determining the greedy choice s[i], we get a new string s' from s by 

  1. removing all letters to the left of s[i],
  2. removing all s[i]'s from s.

We then recursively solve the problem w.r.t. s'. 

The runtime is O(26 * n) = O(n).

public class Solution {    public String removeDuplicateLetters(String s) {        int[] cnt = new int[26];        int pos = 0; // the position for the smallest s[i]        for (int i = 0; i < s.length(); i++) cnt[s.charAt(i) - 'a']++;        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;        }        return s.length() == 0 ? "" : s.charAt(pos) + removeDuplicateLetters(s.substring(pos + 1).replaceAll("" + s.charAt(pos), ""));    }}



0 0