2434. 使用机器人打印字典序最小的字符串

题目描述

给了一个初始字符串s,一个机器人,并且机器人当前有一个字符串t。
可以有两个操作:

  1. 删除s的第一个字符,添加到t的结尾
  2. 删除t的最后一个字符,将字符写到纸上

问纸上能获取到字典序最小的字符串?

基本分析

  1. 两个操作对应的是什么? 将t看做一个栈,操作1代表入栈,操作2对应出栈
  2. 直观上感觉使用贪心来做,但需要考虑怎么贪?
    • 只考虑前后两个字符的关系行不行?简单分析是不行的。例如bca,c比b大,单纯考虑两个关系,b就应该出栈了,而最优的解是b入,c入,a入。
    • 所以需要考虑全局的最小情况,如果全局存在多个最小怎么考虑?加入是bcaada,bca先入,第一个a=后续的最小a,此刻这个a是需要弹出还是继续入队?明显是应该弹出此时栈中是bcd,弹出了3个a,最终结果是aaadcb。
    • 现在问题是怎么能知道剩余的全局最小的情况,这个全局最小是变化的?能想到用Counter去统计,然后遍历到一个字符就维护cnt一次。注意可能存在-1后为0的情况,这个时候怎么办?利用一个while取找满足条件的(个数不为0或者只有最大时会退出while)
    • 有一个细节是,一个字符c入栈以后,出栈怎么考虑,最多是这个字符出吗?答案是只要栈不空并且栈顶元素<=min对应的字符,就应该一直出,这里也是用while实现

代码

栈-哈希表维护剩余最小值-贪心出栈
class Solution:
def robotWithString(self, s: str) -> str:
ans = []
st = []
cnt = Counter(s)
min_ = 0
for c in s:
cnt[c] -= 1
while min_ < 25 and cnt[ascii_lowercase[min_]] == 0:
min_ += 1
st.append(c)
while st and st[-1] <= ascii_lowercase[min_]:
ans.append(st.pop())
return "".join(ans)

复杂度

时间:n为s长度,|Σ|是字符集大小,这里是26。每个字符入队出队最多一次,且min只增不减少,最终复杂度为 O(n+|Σ|)
空间:最差情况下需要n的栈空间,所以是O(n)+|Σ|

总结

  1. 能看出来两个操作和栈的关系
  2. 能看出来用贪心,但是贪心的细节需要考虑清楚。(1)需要剩余的全局min,而不是相邻的大小关系;(2)全局min需要用哈希表存,用while去维护,每-1后进行更新,拿到合适的值;(3)出栈的时候可能是出0出1出多,取决于栈顶和min的关系,这个也是用while去实现
  3. python给了一个列表ascii_lowercase,可以通过索引取出对应小写字母
  4. 结果用列表去存,最后生成字符串
posted @   zhangk1988  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示