📌  相关文章
📜  通过删除重复项形成的字典序最小字符串(1)

📅  最后修改于: 2023-12-03 15:28:24.955000             🧑  作者: Mango

通过删除重复项形成的字典序最小字符串

问题描述

给定一个字符串s,我们可以通过删除字符串中的一些字符来构造出另一个字符串t。假设这里我们希望构造出的t必须满足:

  1. t包含原始字符串s中的所有不同字符;
  2. 在保留不同字符的顺序的情况下,t的字典序要尽可能的小。

举个例子:给定一个字符串s为"cbacdcbc",则我们可以通过删除一些字符,构造出不同的字符串t:例如"acdb"、"abcd"等等。其中,"acdb"是最小的满足条件的字符串。

解决方法

我们可以使用栈这种数据结构来实现本题。

具体地,我们首先遍历字符串s,对于每个字符c,我们判断该字符是不是已经在栈中了。如果c不在栈中,我们就需要考虑t的末尾是否应该加入该字符。我们需要判断的是,如果加入字符c,是否会使得t的字典序不再是最小的。

我们可以观察到,如果栈顶部的元素比字符c大,且后面还有该栈顶的元素,那么我们就可以弹出栈顶元素。这样我们就可以一直判断这样的条件是否成立。如果成立,我们就把栈顶元素弹出,直到栈顶部的元素比字符c小。

最终,我们就可以得到一个不包含重复字符,并且字典序最小的字符串。

代码实现

下面是使用Python对本题的一个实现:

class Solution:
    def removeDuplicateLetters(self, s: str) -> str:
        n = len(s)
        if n <= 1:
            return s

        stack = []
        count = [0] * 26
        for c in s:
            count[ord(c) - ord('a')] += 1

        exists = [False] * 26
        for c in s:
            count[ord(c) - ord('a')] -= 1
            if exists[ord(c) - ord('a')]:
                continue

            while stack and c < stack[-1] and count[ord(stack[-1]) - ord('a')] > 0:
                exists[ord(stack.pop()) - ord('a')] = False

            stack.append(c)
            exists[ord(c) - ord('a')] = True

        return ''.join(stack)

以上就是通过删除重复项形成的字典序最小字符串的解法。