[ LeetCode ] #316. Remove Duplicate Letters(移除重复出现的字符)

本文介绍了一种高效算法,用于去除字符串中的重复字母,确保每个字母只出现一次,并保持结果字符串的字典序最小。通过使用栈思想和统计字符频率,算法能在遍历过程中动态调整结果,避免全排列后的排序,显著提升效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目: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"

题意:

给定一个仅包含小写字母的字符串,移除重复出现的字符,使得每个字符仅出现一次,并且保证得到的结果字母序为最小。

分析:

第一种简单暴力的思路,可以将所有的组合情况求出来 然后排序输出字典序最小的那个,但这种解法时间复杂度必然不符合题目要求。

第二种方法,可以借助stack的思想,首先统计出每个字符出现的次数,然后遍历 每次都将当前位置的字符放置到当前最优的位置,遍历过程中会出现以下几种情况:

  1. 当前遍历字符已经访问过,由上面分析可知,每遍历到一个字符都会将其放置到最优位置,因此当前遍历到的字符可以不做任何处理。
  2. 判断 如果当前用以保存最终结果的字符串ans为空,则说明当前字符为第一个字符,因此 也不需要对其寻找最优位置。那么如果不为空的情况下,则说明当前ans已经包含若干个字符,那么如何使得最终得到的字符串字典序最小呢?即 可以对ans从后往前查找 判断ans.back() 是否大于当前遍历到的字符 并且保证 ans.back()再后续遍历中还会出现,此时就做ans.pop_back()操作,同时将其访问状态置为false,以此找到当前字符的最优位置。
  3. 根据step2,说明已经找到当前情况下 当前字符的最优位置,将当前遍历字符压入结果ans尾部,并标记已访问。
  4. return ans;

Code

class Solution {
public:
    string removeDuplicateLetters(string s) {
       	vector<int> cand(27,0);
        vector<int> visit(27,0);
        for(char c:s)cand[c-'a']++;
        string ans="";
        for(char c:s){
            --cand[c-'a'];
            if(visit[c-'a'])continue;
            while(!ans.empty() && c<ans.back() && cand[ans.back()-'a']){
                visit[ans.back()-'a']=0;
                ans.pop_back();
            }
            ans+=c;
            visit[c-'a']=1;
        }
        return ans;
    }
};

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值