Skip to main content

402.移除K位数字

标签: stack, greedy

难度: Medium

通过率: 34.17%

原题链接: https://leetcode.com/problems/remove-k-digits/description/

题目描述

给定一个代表非负整数的字符串 num 和一个整数 k,要求移除 num 中的 k 位数字,使得剩下的数字形成的整数最小。

解题思路

为了使删除后的数字尽可能小,我们可以使用贪心算法和栈实现。具体方法如下:

  1. 我们遍历数字字符串的每一个字符,对于每个字符,我们尝试将其加入栈中。

  2. 在加入新字符时,如果当前栈顶元素比该字符大,我们可以考虑将栈顶元素移出栈,因为这样可以使更低的数字排在前面。

  3. 为此,我们在加入新字符前应移除不大于 k 个栈顶元素。这样总共移除 k 个元素后,剩余的数字将是最小的。

  4. 遍历过程中,将删除元素的次数累加,未能删除 k 个时,继续从栈中移除。

  5. 最后,将栈中的元素组成一个新的字符串,如果结果中有前导0,则应将其去掉,转为最小的整数。

这种方法有效利用了栈的特性,能够在 O(n) 的时间内完成。

代码实现

# 移除K位数字的Python实现
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 else stack

# 删除前导零并转换为字符串
return ''.join(stack).lstrip('0') or '0'

复杂度分析

时间复杂度为 O(n)O(n),其中 nn 是字符串 num 的长度,因为每个字符至多入栈一次,出栈一次。

空间复杂度为 O(n)O(n),因为栈最多储存所有的字符。