当前位置: 首页 > news >正文

LeetCode 402 - 移掉 K 位数字

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

文章目录

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

摘要

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

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

描述

题目要求如下:

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

例如:

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

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

再看另一个例子:

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

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

最后一种极端情况:

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

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

题解答案

思路其实很自然:

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

题解代码分析

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

import Foundationclass Solution {func removeKdigits(_ num: String, _ k: Int) -> String {var stack: [Character] = []var removeCount = kfor digit in num {// 每当当前数字比栈顶小,就弹出栈顶(相当于删除)while removeCount > 0, let last = stack.last, last > digit {stack.removeLast()removeCount -= 1}stack.append(digit)}// 如果还没删够,就从尾部删除while removeCount > 0, !stack.isEmpty {stack.removeLast()removeCount -= 1}// 构建最终字符串并去掉前导零var result = String(stack).drop(while: { $0 == "0" })return result.isEmpty ? "0" : String(result)}
}// MARK: - 可运行示例
let solution = Solution()
print(solution.removeKdigits("1432219", 3)) // 输出: 1219
print(solution.removeKdigits("10200", 1))   // 输出: 200
print(solution.removeKdigits("10", 2))      // 输出: 0

代码逻辑逐步拆解:

  • 栈的核心思想
    栈用来保存当前有效的数字序列。每个新数字进来之前,都会看一眼栈顶是否“更大”,如果更大,就弹出。
    比如处理 "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”。

示例测试及结果

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

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

输出结果如下:

1219
200
0
0
11

非常符合预期。

时间复杂度

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

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

空间复杂度

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

总结

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

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

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

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

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

http://www.dtcms.com/a/498821.html

相关文章:

  • 皮卡丘XSS
  • 思维|栈
  • 关于网站建设方案的案例数码产品销售网站建设策划书
  • 2025年10月17日
  • Entity Framework Core和SqlSugar的区别,详细介绍
  • 【C语言】运算符
  • 网站备案帐号是什么菏泽微信小程序制作
  • 消息队列以及RabbitMQ的使用
  • PyCharm之服务器篇|Linux连接校园网Neu版
  • 在linux上训练深度学习环境配置(Ubuntu)
  • 洗车小程序系统
  • 网站 备案 营业执照太仓网站设计早晨设计
  • 煤矿网站建设WordPress高端主题 熊
  • 告别炼丹玄学:用元学习精准预测模型性能与数据需求,AWS AI Lab研究解读
  • 无需 VNC / 公网 IP!用 Docker-Webtop+cpolar,在手机浏览器远程操控 Linux
  • Vue3与Cesium:轻量版3D地理可视化实践
  • 数据预处理(音频/图像/视频/文字)及多模态统一大模型输入方案
  • 一段音频多段字幕,让音频能够流畅自然对应字幕 AI生成视频,扣子生成剪映视频草稿
  • Linux-网络安全私房菜(二)
  • 广州外贸网站建设 open需要做网站建设的公司
  • QML学习笔记(四十三)QML与C++交互:上下文属性暴露
  • Redis 的字符串底层实现
  • 递归-206.反转链表-力扣(LeetCode)
  • 【Linux系列】掌控 Linux 的脉搏:深入理解进程控制
  • 百度怎么注册公司网站wordpress 2019主题谷歌字体
  • 算法14.0
  • 基于掌纹生物特征的 Windows 安全登录实践:从物理安全到零信任身份验证
  • uniapp map地图添加浮层
  • 可靠的tcp连接
  • 【uniapp】uni.uploadFile上传数据多出一个304的get请求处理方法