力扣第316与1081题 不同字符的最小子序列 C++ Java Python

目录

题目

思路和解题方法

复杂度:

时间复杂度:O(n)

空间复杂度:O(n)

c++ 代码

Java 版本(仅供参考)

Python 版本(仅供参考)

代码细节


题目

316. 去除重复字母

中等

相关标签

提示

给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的

字典序

最小(要求不能打乱其他字符的相对位置)。

示例 1:

s = "bcabc""abc"

示例 2:

s = "cbacdcbc"
"acdb"

提示:

  • 1 <= s.length <= 104
  • s 由小写英文字母组成

注意:该题与 1081 . - 力扣(LeetCode) 相同

思路和解题方法

  1. 使用栈 stk 存储结果字符串的字符,使用集合 visited 记录栈中已经包含的字符。
  2. 统计每个字符出现的次数,并遍历原始字符串 s
  3. 对于每个字符 ch
    • 减少其出现次数。
    • 如果栈中已经包含了字符 ch,则直接跳过。
    • 如果栈顶元素大于当前字符 ch,且后面还会出现,则将栈顶元素移除。
    • 将字符 ch 添加到栈中,并标记为已访问。
  4. 将栈中字符逆序输出,构成结果字符串。

复杂度:

  • 时间复杂度:O(n)

  • 遍历字符串的时间复杂度为 O(n),其中 n 是字符串的长度。

  • 空间复杂度:O(n)

  • 使用了栈和集合来存储结果字符和已访问字符,以及一个额外的数组来统计字符出现次数,因此空间复杂度为 O(n)。

c++ 代码

#include <string>
#include <stack>
#include <unordered_set>
#include <vector>
using namespace std;

class Solution {
public:
    string smallestSubsequence(string s) {
        stack<char> stk; // 用于存储结果字符串的栈
        unordered_set<char> visited; // 用于记录栈中已经包含的字符
        vector<int> count(26, 0); // 记录每个字符出现的次数

        // 统计每个字符出现的次数
        for (char ch : s) {
            count[ch - 'a']++;
        }

        for (char ch : s) {
            // 对于每个字符ch,首先减少其出现次数
            count[ch - 'a']--;

            // 如果栈中已经包含了字符ch,则直接跳过
            if (visited.count(ch)) {
                continue;
            }

            // 如果栈顶元素大于当前字符ch,且后面还会出现,则将栈顶元素移除
            while (!stk.empty() && stk.top() > ch && count[stk.top() - 'a'] > 0) {
                visited.erase(stk.top());
                stk.pop();
            }

            // 将字符ch添加到栈中,并标记为已访问
            stk.push(ch);
            visited.insert(ch);
        }

        // 将栈中字符逆序输出,构成结果字符串
        string result;
        while (!stk.empty()) {
            result = stk.top() + result;
            stk.pop();
        }

        return result;
    }
};

Java 版本(仅供参考)

import java.util.*;

class Solution {
    public String smallestSubsequence(String s) {
        Stack<Character> stk = new Stack<>(); // 用于存储结果字符串的栈
        Set<Character> visited = new HashSet<>(); // 用于记录栈中已经包含的字符
        int[] count = new int[26]; // 记录每个字符出现的次数

        // 统计每个字符出现的次数
        for (char ch : s.toCharArray()) {
            count[ch - 'a']++;
        }

        for (char ch : s.toCharArray()) {
            // 对于每个字符ch,首先减少其出现次数
            count[ch - 'a']--;

            // 如果栈中已经包含了字符ch,则直接跳过
            if (visited.contains(ch)) {
                continue;
            }

            // 如果栈顶元素大于当前字符ch,且后面还会出现,则将栈顶元素移除
            while (!stk.isEmpty() && stk.peek() > ch && count[stk.peek() - 'a'] > 0) {
                visited.remove(stk.peek());
                stk.pop();
            }

            // 将字符ch添加到栈中,并标记为已访问
            stk.push(ch);
            visited.add(ch);
        }

        // 将栈中字符逆序输出,构成结果字符串
        StringBuilder result = new StringBuilder();
        while (!stk.isEmpty()) {
            result.insert(0, stk.pop());
        }

        return result.toString();
    }
}

Python 版本(仅供参考)

class Solution:
    def smallestSubsequence(self, s: str) -> str:
        stk = []  # 用于存储结果字符串的栈
        visited = set()  # 用于记录栈中已经包含的字符
        count = [0] * 26  # 记录每个字符出现的次数

        # 统计每个字符出现的次数
        for ch in s:
            count[ord(ch) - ord('a')] += 1

        for ch in s:
            # 对于每个字符ch,首先减少其出现次数
            count[ord(ch) - ord('a')] -= 1

            # 如果栈中已经包含了字符ch,则直接跳过
            if ch in visited:
                continue

            # 如果栈顶元素大于当前字符ch,且后面还会出现,则将栈顶元素移除
            while stk and stk[-1] > ch and count[ord(stk[-1]) - ord('a')] > 0:
                visited.remove(stk[-1])
                stk.pop()

            # 将字符ch添加到栈中,并标记为已访问
            stk.append(ch)
            visited.add(ch)

        # 将栈中字符逆序输出,构成结果字符串
        return ''.join(stk)

代码细节

  1. 在 C++ 版本中,unordered_set 是用于记录栈中已经包含的字符,而 vector<int> count(26, 0) 是用于统计每个字符出现的次数。

  2. C++ 中的 stkstack<char> 类型,用于存储结果字符串的字符;visitedunordered_set<char> 类型,用于记录栈中已经包含的字符;countvector<int> 类型,用于记录每个字符出现的次数。

  3. 在 Java 版本中,Stack<Character> 是用于存储结果字符串的栈,Set<Character> 是用于记录栈中已经包含的字符,int[] count 是用于记录每个字符出现的次数。

  4. Python 版本中使用列表 stk 存储结果字符串的字符,集合 visited 记录栈中已经包含的字符,count 为列表,用于记录每个字符出现的次数。

  5. 在遍历字符串时,对于每个字符 ch,首先减少其出现次数 count[ch - 'a']--

  6. 如果栈中已经包含了字符 ch,则直接跳过当前字符。

  7. 如果栈顶元素大于当前字符 ch,且后面还会出现,则将栈顶元素移除。

  8. 将字符 ch 添加到栈中,并标记为已访问。

  9. 将栈中字符逆序输出,构成结果字符串。

觉得有用的话可以点点赞,支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

posted @   lenyan~  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示