力扣 402. 移掉K位数字

题目描述

在这里插入图片描述

我的思路

这道题写了大半天,每一次提交都有部分算例没有测试通过,不断在完善自己解决此问题的逻辑,修改代码。
我最开始想到的是递归,就是先写一个移除1位数字的函数,然后递归K次,在写这个移除1位数字的函数过程当中分了很多种情况去讨论应该怎么选择要移除的那位数字。
最后探索出来的移除步骤为:从头到尾遍历字符串的各位数字→直到发现某位的数字比它下一位的数字大,则移除该位数字→去除移除数字后的字符串的前导0→将移除后的数字作为新的变量进行下一步递归,直到移除的数字达到K个。
但是,基于这个思路写代码我又发现一个问题就是:按照这样的寻找规则,如果到最后发现需要移除的数字数量(即比下一位数字小的数字数量)不足K,那又该怎么继续下去呢?递归似乎变得越来越麻烦,并且时间复杂度也比较高…想了很久也没有想通该如何解决,于是把自己未完全ac的代码丢给了chat-gpt,它给了我一个更好的方法来实现我的思路,即单调栈!

单调栈解题

利用单调栈来实现数字的移除与字符串的更新。以num = “1432219”, k = 5为例,单调栈解题思路如下图。
在这里插入图片描述
该思路代码如下:

class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        # 单调栈:非递减,否则移除
        stack = []
        for digit in num:
            while k > 0 and stack and stack[-1] > digit:
                stack.pop()
                k -= 1
            stack.append(digit)
        stack = stack[:-k] if k > 0 else stack # 如果数字遍历完了但是k位数字还没有完全移除,便从栈顶开始移除,直到满足数量要求。
        
        # 移除前导0
        result = ''.join(stack).lstrip('0')

        return result if result else "0" # 若为空则输出0

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值