leetcode1081. Smallest Subsequence of Distinct Characters


标签: 单调栈

题目

\1081. Smallest Subsequence of Distinct Characters

Medium

Return the lexicographically smallest subsequence of text that contains all the distinct characters of text exactly once.

Example 1:

Input: "cdadabcc"
Output: "adbc"

Example 2:

Input: "abcd"
Output: "abcd"

Example 3:

Input: "ecbacba"
Output: "eacb"

Example 4:

Input: "leetcode"
Output: "letcod"

Note:

  1. 1 <= text.length <= 1000
  2. text consists of lowercase English letters.

greedy wrong answer

DP TLE思路

用map记录所有当前可能存在的状态, 和之前的 1049 last stone weight 2不同,数字的加 加减减可以出想相同的数,进行减枝,字符串无法减枝

单调栈思路

  1. 找到当前位置的单调栈序列(这种纯单调栈的思路很容易)

  2. 所有出现的字符都要出现,有的违背单调原则的字符,通过cnt数组,判断后面是否还会出现,如果不出现,就只能放在违背单调的位置上

  3. 每个字符已经出现了,如果当前字符已经在单调栈的前面了, 那就不用在考虑把他放到单调栈中了,因为单调栈的性质已经保证他在最小的位置上了。使用used判断之前是否已经存在

    小结

    单调栈:最小序列

    cnt:以后该字符是否出现

    used:该字符是否 已经在单调栈中

DP TLE CODE

class Solution {
public:
  bool static cmp(string a, string b){
        int m = a.length();
        for(int i=0; i<m; i++){
            if(a[i] < b[i]){
                continue;
            }else{
                return false;
            }
        }
        return true;
        
    }
    string smallestSubsequence(string text) {
        set<string> strs_a;
        set<string> strs_b;
        string tmp;
        tmp = text[0];
        strs_a.insert(tmp);

        for(int i=0; i<text.length(); i++){
            strs_b = strs_a;
            strs_a.clear();
            for(auto str : strs_b){
                tmp = text[i];
                auto itr = find(begin(str), end(str), text[i]);
                if (itr == end(str)){
                    str+=tmp;
                    strs_a.insert(str);
                }else {
                    strs_a.insert(str);
                    str.erase(itr);
                    str+=tmp;
                    strs_a.insert(str);
                }
            }
        }
        string ans(text.length(), 'z');
        for(auto str : strs_a){
            cout <<str<<endl;
            ans = min(ans, str, cmp);
        }
        return ans;
    }
};

单调栈

//
// Created by hanshan on 19-6-11.
//
#include <vector>
#include <string>
using namespace std;
class Solution {
public:
    string smallestSubsequence(string text) {
        string res = "";
        vector<int> cnt(26);
        vector<int> used(26);
        for(auto ch : text){
            cnt[ch-'a'] ++;
        }

        for(auto ch : text){
            cnt[ch-'a'] --;
            if(used[ch-'a']) continue;
            while( !res.empty() && ch < res.back() && cnt[res.back()-'a']){
                used[res.back()-'a'] = 0;
                res.pop_back();
            }
            res.push_back(ch-'a');
        }
        return res;
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值