贪心策略 + 栈操作:构造字典序最小字符串的最优解

题目链接2434. 使用机器人打印字典序最小的字符串 - 力扣(LeetCode)

题目分析

这道题是一个字符串处理和贪心算法的结合问题。题目描述如下:

给定一个字符串 s,你可以通过以下操作构造一个新字符串 t

  1. 从 s 中移除第一个字符并将其压入栈中。
  2. 从栈顶弹出一个字符并添加到 t 的末尾。

目标是通过合理安排操作顺序,使得构造出的字符串 t 按字典序最小。

解题思路

这个问题可以使用贪心策略来解决。核心思想是每次尽可能地将当前最小的字符添加到结果字符串中。具体步骤如下:

  1. 统计字符频率:首先统计字符串中每个字符的出现次数,以便后续快速判断某个字符是否已经全部处理完毕。

  2. 维护当前最小字符:使用一个变量 minCharacter 来跟踪当前可以使用的最小字符。初始值为 'a',并在处理过程中动态调整。

  3. 遍历字符串:遍历原字符串中的每个字符,将其压入栈中,并减少该字符的计数。

  4. 调整最小字符:每次处理一个字符后,检查当前的 minCharacter 是否还有剩余。如果没有,则递增 minCharacter 直到找到下一个还有剩余的字符。

  5. 弹出栈顶元素:检查栈顶元素是否小于或等于当前的 minCharacter,如果是,则将其弹出并添加到结果字符串中,直到栈为空或栈顶元素大于 minCharacter

代码实现

class Solution {
public:
    string robotWithString(string s) {
        unordered_map<char, int> cnt;
        for (char c : s) {
            cnt[c]++;
        }

        stack<char> stk;
        string res;
        char minCharacter = 'a';
        for (char c : s) {
            stk.emplace(c);
            cnt[c]--;
            while (minCharacter != 'z' && cnt[minCharacter] == 0) {
                minCharacter++;
            }
            while (!stk.empty() && stk.top() <= minCharacter) {
                res.push_back(stk.top());
                stk.pop();
            }
        }
        
        return res;
    }
};

复杂度分析

  • 时间复杂度:O (n),其中 n 是字符串的长度。每个字符最多被处理两次(一次入栈,一次出栈),并且每次调整 minCharacter 的总次数不超过 26 次。

  • 空间复杂度:O (n),主要是栈的空间开销,最坏情况下栈可能存储整个字符串。

关键点解释

  1. 贪心策略:通过维护当前最小字符,确保每次尽可能地将最小字符添加到结果中,从而保证最终字符串字典序最小。

  2. 频率统计:使用哈希表统计字符频率,快速判断某个字符是否已经全部处理完毕。

  3. 栈的应用:栈用于临时存储字符,允许在适当的时候弹出字符,调整结果字符串的顺序。

  4. 动态调整最小字符:每次处理字符后,动态更新当前可以使用的最小字符,确保算法的正确性。

通过这种方法,我们可以高效地构造出字典序最小的字符串。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.wei-upup

如若对您有用,盼您赏个鼓励~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值