题目描述
我的思路
这道题写了大半天,每一次提交都有部分算例没有测试通过,不断在完善自己解决此问题的逻辑,修改代码。
我最开始想到的是递归,就是先写一个移除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