LeetCode 402 - 移掉 K 位数字

作者:网罗开发日期:2025/10/19

在这里插入图片描述
在这里插入图片描述

文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
      • 代码逻辑逐步拆解:
    • 示例测试及结果
    • 时间复杂度
    • 空间复杂度
    • 总结

摘要

在很多前端或后端的业务逻辑中,我们经常要处理数字的“裁剪”问题,比如在账单明细里自动保留最小金额组合、或在数据压缩时尽量保留较小值。LeetCode 第 402 题《移掉 K 位数字》(Remove K Digits)就是一个非常贴近这种逻辑的算法题。

题目的核心是:给定一个非负整数(以字符串形式表示),从中移除 k 个数字,使得剩下的数字最小化。
看似简单,但要保证最小值且保持相对顺序,就必须巧妙地使用单调栈(Monotonic Stack)

描述

题目要求如下:

给你一个以字符串表示的非负整数 num 和一个整数 k,移除这个数中的 k 位数字,使得剩下的数字最小。返回结果仍然以字符串形式表示。

例如:

1输入:num = "1432219", k = 3
2输出:"1219"
3

解释:
我们删掉 4、3、2,得到 1219,这是最小的组合。

再看另一个例子:

1输入:num = "10200", k = 1
2输出:"200"
3

因为去掉开头的 1 后,最小结果是 “200”,同时要注意不能有前导零。

最后一种极端情况:

1输入:num = "10", k = 2
2输出:"0"
3

删光了,只能输出 “0”。

题解答案

思路其实很自然:

  1. 我们想要一个尽可能小的数字。
  2. 所以,每当我们看到一个“比前一个更小”的数字,就说明前面的数字没必要留着,可以删掉让整体更小。
  3. 这正是典型的 “单调递增栈” 思想。
    我们用一个栈来存放数字,如果当前数字比栈顶小,就把栈顶弹出(删掉)直到不满足条件或删够了 k 个。
  4. 最后,如果还没删够,就从尾部继续删。
  5. 结果去掉前导零,若为空返回 “0”。

题解代码分析

下面是完整的 Swift 实现,可以直接在 Xcode 或 Playground 中运行:

1import Foundation
2
3class Solution {
4    func removeKdigits(_ num: String, _ k: Int) -> String {
5        var stack: [Character] = []
6        var removeCount = k
7
8        for digit in num {
9            // 每当当前数字比栈顶小,就弹出栈顶(相当于删除)
10            while removeCount > 0, let last = stack.last, last > digit {
11                stack.removeLast()
12                removeCount -= 1
13            }
14            stack.append(digit)
15        }
16
17        // 如果还没删够,就从尾部删除
18        while removeCount > 0, !stack.isEmpty {
19            stack.removeLast()
20            removeCount -= 1
21        }
22
23        // 构建最终字符串并去掉前导零
24        var result = String(stack).drop(while: { $0 == "0" })
25        return result.isEmpty ? "0" : String(result)
26    }
27}
28
29// MARK: - 可运行示例
30let solution = Solution()
31print(solution.removeKdigits("1432219", 3)) // 输出: 1219
32print(solution.removeKdigits("10200", 1))   // 输出: 200
33print(solution.removeKdigits("10", 2))      // 输出: 0
34

代码逻辑逐步拆解:

  • 栈的核心思想
    栈用来保存当前有效的数字序列。每个新数字进来之前,都会看一眼栈顶是否“更大”,如果更大,就弹出。
    比如处理 "1432219"
    • 1 → [1]
    • 4 → [1, 4]
    • 3 → 3 < 4 → 弹出 4 → [1, 3]
    • 2 → 2 < 3 → 弹出 3 → [1, 2]
    • 2 → [1, 2, 2]
    • 1 → 1 < 2 → 弹出两个 2 → [1, 1]
    • 9 → [1, 1, 9]
      最终得到 1219
  • 删除次数控制
    我们用 removeCount 计数,每次弹出一个数字就减 1。
    如果循环结束后还没删够,就直接从尾巴删,保持最小化。
  • 前导零处理
    比如 “10200” → 删除 1 后变成 “0200”,要去掉前导零,得到 “200”。

示例测试及结果

我们来跑几组不同的示例看看结果是否符合预期。

1let solution = Solution()
2print(solution.removeKdigits("1432219", 3)) // 1219
3print(solution.removeKdigits("10200", 1))   // 200
4print(solution.removeKdigits("10", 2))      // 0
5print(solution.removeKdigits("1234567890", 9)) // 0
6print(solution.removeKdigits("112", 1))     // 11
7

输出结果如下:

11219
2200
30
40
511
6

非常符合预期。

时间复杂度

  • 主循环中每个数字最多入栈、出栈一次,
    所以整体复杂度是 O(n),其中 n 是字符串长度。

这种复杂度对于 num.length 高达 10^5 的情况也能轻松应对。

空间复杂度

  • 我们用了一个栈来存储数字,最坏情况下保存所有字符,
    所以空间复杂度是 O(n)

总结

这道题看似是个字符串问题,其实本质是个“贪心 + 单调栈”的组合问题。

  • 贪心保证我们每一步都尽可能让左边数字小;
  • 栈保证我们能方便地删除不合适的数字;
  • 去除前导零的细节让结果符合格式要求。

在实际开发中,这种思想也很常见,比如:

  • 表单验证时自动修剪冗余字符
  • 财务系统中压缩冗余金额字段
  • UI 中动态展示最小数值状态

这道题不仅是算法题,更像是“如何在一堆数里精简出最优解”的典型案例。


LeetCode 402 - 移掉 K 位数字》 是转载文章,点击查看原文


相关推荐


谷歌 × 耶鲁联手发布抗癌神器!AI 推理精准狙击「隐身」癌细胞
新智元2025/10/17

「【新智元导读】近日,谷歌与耶鲁大学联合发布的大模型 C2S-Scale,首次提出并验证了一项全新的「抗癌假设」。这一成果表明,大模型不仅能复现已知科学规律,还具备生成可验新科学假设的能力。」 刚刚,AI 科学应用领域又有一件大事发生! 谷歌与耶鲁大学的科学家们联合发布了一个大模型 Cell2Sentence-Scale 27B(C2S-Scale)。 该模型提出了一个关于癌细胞行为的全新假设,并在多次体外实验中得到验证。 这一发现引发广泛关注,它展示了人工智能模型生成原创科学假设的潜力,有望


【ComfyUI】Animate单人物角色视频替换
Mr数据杨2025/10/16

在智能创作和视频生成的实践中,工作流不仅仅是节点的堆叠,而是一个围绕业务目标、数据流转和模型能力的有机整体。通过对工作流的抽象与模块化设计,我们可以在复杂的生成任务中实现高效的可复用性与灵活性。本篇文章将围绕某实际业务场景展开,介绍完整的工作流结构,并重点解析核心模型与节点配置方式,帮助读者从整体视角理解其逻辑与实现。 文章目录 工作流核心模型工作 Node 节点工作流程应用场景 开发与应用 工作流 一个完整的工作流是由数据输入、模型处理、结果合成和输出展示构成的有机链路。


如何在Linux服务器上部署jenkins?
Broken Arrows2025/10/15

一,首先安装JAVA环境 Java8、java11、java17(JRE或者 JDK都可以),从 Jenkins2.357(于2022年6月28日发布)和2.361.1LTS版本开始,Jenkins需要Java11或更高版本。此外,从Jenkins2.355(2022年6月14日发布和Jenkins2.346,1LTS(2022年6月22日发布)开始,Jenkins支持Java 17。 一般我们推荐使用包管理器来进行安装,我这里使用的是Ubuntu的系统,在这里给以下步骤做参考。 # 更新


将 GPU 级性能带到企业级 Java:CUDA 集成实用指南
程序猿DD2025/10/13

引言 在企业软件世界中,Java 依靠其可靠性、可移植性与丰富生态持续占据主导地位。 然而,一旦涉及高性能计算(HPC)或数据密集型作业,Java 的托管运行时与垃圾回收开销会在满足现代应用的低延迟与高吞吐需求上带来挑战,尤其是那些涉及实时分析、海量日志管道或深度计算的场景。 与此同时,最初为图像渲染设计的图形处理器(GPU)已成为并行计算的实用加速器。 像 CUDA 这样的技术让开发者能够驾驭 GPU 的全部算力,在计算密集型任务上获得显著的加速效果。 但问题在于:CUDA 主要面向 C/C+


服务端之NestJS接口响应message编写规范详解、写给前后端都舒服的接口、API提示信息标准化
焊码IoT2025/10/12

MENU 前言定义提示信息设计原则提示信息风格分类提示信息模板化设计国际化与多语言支持最佳实践参考示例(NestJS响应)总结统一风格示例清单推荐API响应message清单(可直接使用) 前言 在现代后端开发中,接口响应不仅仅是数据的传递,还承担着向前端或用户传递操作状态和结果的功能。一个规范、统一的message字段设计,可以显著提升系统的可维护性、前端开发效率和用户体验。 定义 响应结构示例(NestJS风格) return { statu


Ling-1T:蚂蚁百灵如何以“非思考”策略,开启万亿参数效率新篇章?
墨风如雪2025/10/10

2025年10月9日,AI世界再次被一颗“重磅炸弹”点燃。蚂蚁集团百灵大模型团队正式发布了其Ling 2.0系列的首款旗舰模型——Ling-1T。这不仅仅是一个拥有万亿参数的通用大语言模型,它更代表着蚂蚁集团在大模型设计理念上的一次大胆创新和实践突破。它已全面开源,正等待着全球开发者共同探索其无限潜力。 “非思考”定位:速度与精准的完美结合 初听“非思考模型”,你或许会感到好奇。这并非 Ling-1T 不具备推理能力,而是蚂蚁集团对大模型家族的一种策略性划分。在百灵模型矩阵中,“Ling系列”


C# 泛型(Generic)
wjs20242025/10/9

C# 泛型(Generic) 泛型是C#编程语言中一种强大的功能,它允许我们在不具体指定数据类型的情况下编写代码。这种设计模式使得代码更加通用、灵活,并且可以避免类型转换的错误。下面将详细探讨C#泛型的概念、应用场景、实现方法以及相关最佳实践。 泛型的概念 在C#中,泛型允许我们定义可以支持多种数据类型的类或方法。这种类型参数化的机制使得代码更加通用,从而减少了类型转换的需要,并提高了代码的复用性。 泛型的好处 代码复用:通过泛型,我们可以定义一次模板,然后在多个地方复用。


Spring Boot 实现微信登录,So Easy !
皮皮林5512025/10/7

前言 小程序登录在开发中是最常见的需求,哪怕小程序登录不是你做,你还是要了解一下流程,后续都要使用到openId和unionId,你需要知道这些是干什么的。 需求分析 点击登录会弹出弹窗,需要获取用户手机号进行登录。 图片 微信登录业务逻辑规则: 图片 思路说明 参考微信官方文档的提供的思路,官方文档: developers.weixin.qq.com/miniprogram… 微信官方推荐登录流程: 图片 注意点: • 前端在小程序集成微信相关依赖,调用wx.login获取临时登录


uniapp微信小程序安卓手机Touchend事件无法触发
一诺滚雪球2025/10/6

前言 在使用uniapp开发微信小程序时,需要做一个下拉功能,使用touch事件实现。实际情况出现了touchend事件无法触发的情况。 如何解决呢? 1. 解决方案 移动项目开发过程中,经常需要用到滑动的事件来处理一些效果。正常情况下,我们会通过  touchstart->touchmove->touchend  的过程来定义这个事件。这些事件的触发顺序是  touchstart, touchmove, touchmove ….. touchend。 绝大部分平板或手机是这样有序执行。但是以A


Python 的内置函数 anext
IMPYLH2025/10/4

Python 内建函数列表 > Python 的内置函数 anext 如果你熟悉 next() 函数,那么 anext 就是它的异步版本,专为异步迭代器(async for 循环)设计。随着 Python 异步编程(asyncio)的普及,anext 在协程(coroutine)环境下提供了更优雅的方式来获取异步迭代器的下一个值。 anext 的函数原型如下: async def anext(async_iterator): ''' 获取异步迭代器的下一数据项, 没

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0