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

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

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

这是一个字符串处理问题,给定一个字符串,要求将字符串中的重复字符删除,得到字典序最小的字符串。

解题思路

首先,需要明确一个概念:什么是字典序?

字典序是一种比较方法,常常用来排序。对于两个字符串 A 和 B,如果 A 字典序小于 B,那么我们会把 A 排在 B 前面。如果 A 和 B 字典序相同,那么我们要继续比较两个字符串的下一个字符,直到找到一个不同的字符或者其中一个字符串已经没有下一个字符了。比较字符的时候,可以直接比较字符的 ASCII 码值大小。

对于本问题,我们可以考虑用一个栈来辅助求解。具体步骤如下:

  1. 从左到右遍历字符串,对于每个字符,判断当前字符是否已经在栈中出现过。如果已经出现过,那么就跳过这个字符。
  2. 如果当前字符没有在栈中出现过,就需要把它插入到栈中,并且要保证新插入的字符比之前的字符字典序更小。所以,我们需要弹出栈中比当前字符大的字符,保证最终得到的字符串字典序最小,并把当前字符插入栈中。
  3. 遍历完字符串之后,栈中存储的字符就是要求得的字典序最小的字符串。从栈底到栈顶依次取出字符,构成最终的结果字符串。
代码实现

以下是 Python 3 代码实现:

class Solution:
    def removeDuplicateLetters(self, s: str) -> str:
        stack, count = [], {}
        for ch in s: # 统计每个字符出现的次数
            count[ch] = count.get(ch, 0) + 1
        visited = set() # 标记字符是否已经出现在栈中
        for ch in s:
            count[ch] -= 1 # 每遍历一个字符,就将其剩余出现次数减一
            if ch in visited: # 如果字符已经在栈中出现过,就跳过
                continue
            while stack and stack[-1] > ch and count[stack[-1]] > 0:
                visited.remove(stack[-1]) # 弹出比当前字符大的字符,统计字符出现次数
                stack.pop()
            visited.add(ch)
            stack.append(ch)
        return ''.join(stack)
时间复杂度分析

假设字符串长度为 n,我们需要遍历两次字符串。第一次遍历用于统计每个字符出现的次数,时间复杂度为 O(n);第二次遍历用于构造最终的结果字符串,时间复杂度为 O(n)。

在第二次遍历过程中,每个字符最多被压入栈一次,也最多被弹出栈一次,所以时间复杂度为 O(n)。

综上所述,本算法的时间复杂度为 O(n)。