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"

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

这道题让我们移除重复字母,使得每个字符只能出现一次,而且结果要按字母顺序排,前提是不能打乱其原本的相对位置。我们的解题思路是:先建立一个哈希表来统计每个字母出现的次数,还需要一个visited数字来纪录每个字母是否被访问过,我们遍历整个字符串,对于遍历到的字符,先在哈希表中将其值减一,然后看visited中是否被访问过,若访问过则继续循环,说明该字母已经出现在结果中并且位置已经安排妥当。如果没访问过,我们和结果中最后一个字母比较,如果该字母的ASCII码小并且结果中的最后一个字母在哈希表中的值不为0(说明后面还会出现这个字母),那么我们此时就要在结果中删去最后一个字母且将其标记为未访问,然后加上当前遍历到的字母,并且将其标记为已访问,以此类推直至遍历完整个字符串s,此时结果里的字符串即为所求。这里有个小技巧,我们一开始给结果字符串res中放个"0",就是为了在第一次比较时方便,如果为空就没法和res中的最后一个字符比较了,而‘0’的ASCII码要小于任意一个字母的,所以不会有问题。最后我们返回结果时再去掉开头那个‘0’即可,参见代码如下:

class Solution {
public:
string removeDuplicateLetters(string s) {
int m[] = {}, visited[] = {};
string res = "";
for (auto a : s) ++m[a];
for (auto a : s) {
--m[a];
if (visited[a]) continue;
while (a < res.back() && m[res.back()]) {
visited[res.back()] = ;
res.pop_back();
}
res += a;
visited[a] = ;
}
return res.substr();
}
};

这道题如果用Java解题的话可以使用一种递归的方法,参见这里。思路是:先用哈希表记录每个字母出现的次数,再遍历给定字符串s,找出最小的字母,每比较一个字母,在哈希表中的值减1,如果此时为0了,则不继续遍历了,此时我们记录了一个位置,把字符串s中该位置左边的字符都删掉,右边的所有再出现的该字母也删掉,递归调用此函数即可,在Java中可以使用replaceAll函数,我用STL自己写了一个无法通过OJ的大数据,可能实现方法不对吧。。。

参考资料:

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

https://leetcode.com/discuss/75529/c-simple-solution-easy-understanding

https://leetcode.com/discuss/73761/a-short-o-n-recursive-greedy-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

最新文章

  1. 一个简单移动页面ionic打包成app
  2. Windows系统变量
  3. Android IOS WebRTC 音视频开发总结(八十一)-- WebRTC靠谱吗?有没有适合的SDK推荐?
  4. stack overflow错误分析
  5. 6、httpd服务的安装、配置
  6. iOS-微信-分享
  7. JavaScript中判断为整数的多种方式
  8. 解决点击状态栏时ScrollView自动滚动到初始位置失效办法
  9. C#基础-Func,Action
  10. jedis连接池详解(Redis)
  11. spring常用的连接池属性文件配置
  12. 一个CS出身的基本素养
  13. HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
  14. Gas Station [leetcode] 两个解决方案
  15. python抓取数据构建词云
  16. js中slice splice substring substr区别
  17. C++ 常用设计模式(学习笔记)
  18. 【LeetCode225】 Implement Stack using Queues★
  19. OpenGL chapter4 基础变换
  20. VS 类快捷键

热门文章

  1. Oracle迁移:Linux-&gt;Windows
  2. Android指纹识别深入浅出分析到实战(6.0以下系统适配方案)
  3. 在CentOS 7/6.5/6.4 中安装Java JDK 8(转载)
  4. MySQL时间分组查询
  5. 如何写出安全的API接口?接口参数加密签名设计思路
  6. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.2
  7. Java名字的由来
  8. 深入理解javascript选择器API系列第二篇——getElementsByClassName
  9. SharePoint 2013 入门教程
  10. [Android]Android MVP&amp;依赖注入&amp;单元测试