题目链接2434. 使用机器人打印字典序最小的字符串 - 力扣(LeetCode)
题目分析
这道题是一个字符串处理和贪心算法的结合问题。题目描述如下:
给定一个字符串 s
,你可以通过以下操作构造一个新字符串 t
:
- 从
s
中移除第一个字符并将其压入栈中。 - 从栈顶弹出一个字符并添加到
t
的末尾。
目标是通过合理安排操作顺序,使得构造出的字符串 t
按字典序最小。
解题思路
这个问题可以使用贪心策略来解决。核心思想是每次尽可能地将当前最小的字符添加到结果字符串中。具体步骤如下:
-
统计字符频率:首先统计字符串中每个字符的出现次数,以便后续快速判断某个字符是否已经全部处理完毕。
-
维护当前最小字符:使用一个变量
minCharacter
来跟踪当前可以使用的最小字符。初始值为 'a',并在处理过程中动态调整。 -
遍历字符串:遍历原字符串中的每个字符,将其压入栈中,并减少该字符的计数。
-
调整最小字符:每次处理一个字符后,检查当前的
minCharacter
是否还有剩余。如果没有,则递增minCharacter
直到找到下一个还有剩余的字符。 -
弹出栈顶元素:检查栈顶元素是否小于或等于当前的
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),主要是栈的空间开销,最坏情况下栈可能存储整个字符串。
关键点解释
-
贪心策略:通过维护当前最小字符,确保每次尽可能地将最小字符添加到结果中,从而保证最终字符串字典序最小。
-
频率统计:使用哈希表统计字符频率,快速判断某个字符是否已经全部处理完毕。
-
栈的应用:栈用于临时存储字符,允许在适当的时候弹出字符,调整结果字符串的顺序。
-
动态调整最小字符:每次处理字符后,动态更新当前可以使用的最小字符,确保算法的正确性。
通过这种方法,我们可以高效地构造出字典序最小的字符串。