开始的思路是遍历存储每个字符的所有位置,再进行扫描处理,但是实际操作并没有很熟练,于是在讨论区学习后,有了下面的解法!

首先需要知道不同的字符在字符串中的最后的位置(理论上的最优位置)

然后扫描字符串进行处理;这里有几个规则:

  1. 对于不同的字符,字典序靠前的字符应该相对于靠后的字符在位置上尽可能靠前(即index较小);

  2. 依次扫描字符串,每一次需要看是否在stack中存下了字符ch1,如果没有,需要和栈顶的字符ch2进行比较,如果栈顶的字符ch2在字典序中大于ch1且ch2在字符串中的最后的位置比此时的index大,那么栈顶元素弹出(同时其标志位恢复),将ch1压入stack;否则直接把ch1压入stack;

  3. 对于一个已经和另外一个字符进行比较确定位置的字符,其位置应该在之后的操作不更改:这里举例:

    先扫描e,下一个字符是c,且e的位置无法变更,只能在c的前面,即之前保存的e的最后的位置就是此时的index;继续扫描,下一个字符b和c进行比较,这里,会发现,e相对于b,和e相对于c是一样的道理,甚至,如果c 的最后的位置在此时b的后面,那么我们就把c先取消,这时,e相对于b的位置仍无需变换,eb甚至优于之前的ec

  4. 对于已经压入栈的字符,再次遇到时不需要处理,因为之前的位置应该是良好的字典序,再次处理然而会导致字符重复且字典序变差;

具体代码如下:

class Solution {
public:
string smallestSubsequence(string text) {
stack<char> st;
vector<int> final(128, 0);
vector<bool> mark(128, 0);
for(int i = 0; i < text.size(); i++) {
final[text[i]] = i;
} for(int i = 0; i < text.size(); i++) {
if (mark[text[i]])
continue; while(st.size() and st.top() > text[i] and final[st.top()] > i) {
mark[st.top()] = false;
st.pop();
}
st.push(text[i]);
mark[text[i]] = true;
}
string result = "";
while(st.size() > 0) {
result += st.top();
st.pop();
}
reverse(result.begin(), result.end());
return result;
}
};

以上为参考讨论区的改编!原答案链接

https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/discuss/344686/CPP-or-EASY-or-100-BEATS-TIME-AND-MEM-or-SMALL

leetcode 1081的更多相关文章

  1. LeetCode 1081. Smallest Subsequence of Distinct Characters

    原题链接在这里:https://leetcode.com/problems/smallest-subsequence-of-distinct-characters/ 题目: Return the le ...

  2. 【leetcode】1081. Smallest Subsequence of Distinct Characters

    题目如下: Return the lexicographically smallest subsequence of text that contains all the distinct chara ...

  3. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

  4. 我竟在arm汇编除法算法里找到了leetcode某道题的解法

    今天讲讲arm汇编中除法的底层实现.汇编代码本身比较长了,如需参考请直接拉到文末. 下面我直接把arm的除法算法的汇编代码转译成C语言的代码贴出来,并进行解析. 因为篇幅有限,所以在此只解析无符号整型 ...

  5. 我为什么要写LeetCode的博客?

    # 增强学习成果 有一个研究成果,在学习中传授他人知识和讨论是最高效的做法,而看书则是最低效的做法(具体研究成果没找到地址).我写LeetCode博客主要目的是增强学习成果.当然,我也想出名,然而不知 ...

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

    终于将LeetCode的免费题刷完了,真是漫长的第一遍啊,估计很多题都忘的差不多了,这次开个题目汇总贴,并附上每道题目的解题连接,方便之后查阅吧~ 477 Total Hamming Distance ...

  7. [LeetCode] Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子字符串

    Find the length of the longest substring T of a given string (consists of lowercase letters only) su ...

  8. Leetcode 笔记 113 - Path Sum II

    题目链接:Path Sum II | LeetCode OJ Given a binary tree and a sum, find all root-to-leaf paths where each ...

  9. Leetcode 笔记 112 - Path Sum

    题目链接:Path Sum | LeetCode OJ Given a binary tree and a sum, determine if the tree has a root-to-leaf ...

随机推荐

  1. linux程序开机自动启动

    linux如果需要实现开机启动, 可以找到 $HOME/.config/autostart 目录(没有的话新建一个),在该文件夹下创建一个空文件,文件名自拟,后缀必须是desktop,如:dingda ...

  2. C# .NET Socket 简单实用框架,socket组件封装

    参考资料 https://www.cnblogs.com/coldairarrow/p/7501645.html 根据.NET Socket 简单实用框架进行了改造,这个代码对socket通信封装还是 ...

  3. $@ 与 $* 差在哪?-- Shell十三问<第九问>

    $@ 与 $* 差在哪?-- Shell十三问<第九问> 要说 $@ 与 $* 之前,需得先从 shell script 的 positional parameter 谈起.我们都已经知道 ...

  4. django-自定义用户登录(个人笔记)

    django自定义用户登录(个人笔记) 函数说明 1. render()函数:对用户请求做出响应 2. path()函数:定义路由 3. create()函数:增加数据表记录 配置settings.p ...

  5. 【笔记】《Redis设计与实现》chapter18 发布与订阅

    chapter18 发布与订阅 客户端订阅频道. 客户端向频道发送消息, 消息被传递至各个订阅者. 匹配模式 客户端订阅模式. 客户端向频道发送消息, 消息被传递给正在订阅匹配模式的订阅者. 另一个模 ...

  6. Java实现操作系统中四种动态内存分配算法:BF+NF+WF+FF

    1 概述 本文是利用Java实现操作系统中的四种动态内存分配方式 ,分别是: BF NF WF FF 分两部分,第一部分是介绍四种分配方式的概念以及例子,第二部分是代码实现以及讲解. 2 四种分配方式 ...

  7. Score UVA - 1585

    ​ There is an objective test result such as "OOXXOXXOOO". An 'O' means a correct answer of ...

  8. 如何把 Caffeine Cache 用得如丝般顺滑?

    一.关于 Caffeine Cache 在推荐服务中,虽然允许少量请求因计算超时等原因返回默认列表.但从运营指标来说,越高的"完算率"意味着越完整的算法效果呈现,也意味着越高的商业 ...

  9. ASP去除所有html标签

    ASP去除所有html标签 function nohtml(str) dim re Set re=new RegExp re.IgnoreCase =true re.Global=True re.Pa ...

  10. 【Java集合】JDK1.7和1.8 HashMap有什么区别

    JDK1.7和1.8 HashMap区别: 1.数组+链表改成了数组+链表或红黑树: 2.表的插入方式从头插法改成了尾插法,简单说就是插入时,如果数组位置上已经有元素,1.7将新元素放到数组中,原始节 ...