leetcode 316. Remove Duplicate Letters

56 篇文章 0 订阅
53 篇文章 0 订阅

一些感想

昨天去听了网易互娱的宣讲会,不得不说确实是中国最优秀的公司之一,也确实值得我把它作为明年找工作的目标。面试官的想表达的核心就是,要证明你是足够优秀和足够聪明的。加油!

题目描述

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”

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

题目分析

本题说实话题目是比较绕的,得多花点儿时间去理解题目意思。简单解释一下,最终的目标是去除字符串内的重复字母,并且最终得到的序是所有可能序的最小排序(所谓最小排序,就是指在相对顺序不变的情况下,得到的序是字典序中最小的)。以”cbacdcbc”为例,我们知道,可能得到的序可能有 cbad bacd acdb等(分别删除不同位置的重复字母)。我们知道acdb是满足条件的最小序。我们观察一下是如何得出上述结论的:首先,先确认第一个字符a,我们从第一个元素开始,假设是c,我们发现,在a的右侧仍然存在c,所以c必然不是第一个元素,同样的道理,b也不可能是第一个元素,但是,如果b或c只存在一个元素,那么他们就应该是最小的第一个元素(保证原序列)。所以这个问题是一个贪婪算法可以解决的问题,我们每次按上述算法找最左侧的最小元素,然后在剩下的字符中递归查找,直到字符串为空。注意,我们判断当前最小元素的条件是,某个字符出现的次数递减至0,也就是说,最小元素只可能出现在该字符当前位置之前,这与我们先前的分析吻合。

代码实现(贪婪算法)

class Solution {
public:
    string removeDuplicateLetters(string s) {
        // greedy solution
        if(s.empty()) return "";
        vector<int> greedy(26,0);
        for(auto v:s) greedy[v-'a']++;
        int pos = 0;
        for(int i = 0;i<s.size();++i) {
            if(s[i]<s[pos]) pos = i;
            if(--greedy[s[i]-'a'] == 0) break;
        }
        char ret = s[pos];
        string recusive;
        for(int i = pos+1;i<s.size(); ++i) {
            auto val = s[i];
            if(val == ret) continue;
            recusive+=val;
        }
        return ret+removeDuplicateLetters(recusive);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值