📅  最后修改于: 2023-12-03 14:58:03.781000             🧑  作者: Mango
问题描述:给定一个字符串s,通过从s中仅删除一个字符,找出可能的字典序最小的子序列。
例如:s = "bcabc"。
我们可以删除b和c得到字典序最小的子序列"aabc"。
思路:这是一个典型的栈的应用场景。我们可以用一个栈来维护当前获取的子序列。对于任意一个字符,如果这个字符比栈顶的字符小,并且栈顶的字符在后面还会出现,那么我们就把栈顶的字符弹出。
算法过程:
我们初始化一个栈和一个字典last_occurrence,用字典记录每个字符最后一次出现的位置。
遍历字符串s中的每个字符c,执行以下操作:
a. 如果栈不为空,且c比栈顶元素小,并且栈顶元素在后面还会出现,那么我们就把栈顶元素弹出。
b. 如果c在last_occurrence中没有记录,我们直接把c压入栈中。
c. 在last_occurrence中记录c的位置。
把栈中的元素弹出,这就是我们的最终答案。
代码演示:
def smallest_subsequence(s: str) -> str:
last_occurrence = {c: i for i, c in enumerate(s)}
stack = []
for i, c in enumerate(s):
if c in stack:
continue
while stack and c < stack[-1] and i < last_occurrence[stack[-1]]:
stack.pop()
stack.append(c)
return ''.join(stack)
代码解释:
第一步中,我们用字典last_occurrence记录每个字符最后一次出现的位置,用stack来维护当前的子序列。
第二步中,我们遍历字符s中的每个字符c,执行以下操作:
a. 如果栈不为空,且c比栈顶元素小,并且栈顶元素在后面还会出现,我们就把栈顶元素弹出。
b. 如果c在last_occurrence中没有记录,我们直接把c压入栈中。
c. 在last_occurrence中记录c的位置。
第三步中,我们把栈中的元素弹出,这就是我们的最终答案。
总结:
这是一个经典的栈的应用场景,通过维护一个栈和一个字典,我们可以解决这个问题。这里需要注意的是,在遍历字符串s中的每个字符c时,我们不能直接忽略掉已经在栈中的字符,因为删除栈中的字符,可能会得到更小的字典序子序列。