Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

Note:

  • The length of num is less than 10002 and will be ≥ k.
  • The given num does not contain any leading zero.

Example 1:

Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.

Example 2:

Input: num = "10200", k = 1
Output: "200"
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.

Example 3:

Input: num = "10", k = 2
Output: "0"
Explanation: Remove all the digits from the number and it is left with nothing which is 0.

这道题让我们将给定的数字去掉k位,要使得留下来的数字最小,这题跟 LeetCode 上之前那道 Create Maximum Number 有些类似,可以借鉴其中的思路,如果n是 num 的长度,我们要去除k个,那么需要剩下 n-k 个,怎么判断哪些数字应该去掉呢?首先来考虑,若数字是递增的话,比如 1234,那么肯定是要从最后面移除最大的数字。若是乱序的时候,比如 1324,若只移除一个数字,移除谁呢?这个例子比较简单,我们一眼可以看出是移除3,变成 124 是最小。但是怎么设计算法呢,实际上这里利用到了单调栈的思想,可以参见博主之前的一篇总结帖 LeetCode Monotonous Stack Summary 单调栈小结。这里我们维护一个递增栈,只要发现当前的数字小于栈顶元素的话,就将栈顶元素移除,比如点那个遍历到2的时候,栈里面有1和3,此时2小于栈顶元素3,那么将3移除即可。为何一定要移除栈顶元素呢,后面说不定有更大的数字呢?这是因为此时栈顶元素在高位上,就算后面的数字再大,也是在低位上,我们只有将高位上的数字尽可能的变小,才能使整个剩下的数字尽可能的小。这里虽然利用了单调栈的思想,但我们并不用真正用栈 stack 的数据结构,直接用个字符串就行了,因为字符串 string 也可以移除末尾字符。我们开始遍历给定数字 num 的每一位,对于当前遍历到的数字c,进行如下 while 循环,如果 res 不为空,且k大于0,且 res 的最后一位大于c,那么应该将 res 的最后一位移去,且k自减1。当跳出 while 循环后,我们将c加入 res 中,最后将 res 的大小重设为 n-k。根据题目中的描述,可能会出现 "0200" 这样不符合要求的情况,所以我们用一个 while 循环来去掉前面的所有0,然后返回时判断是否为空,为空则返回 “0”,参见代码如下:

解法一:

class Solution {
public:
string removeKdigits(string num, int k) {
string res = "";
int n = num.size(), keep = n - k;
for (char c : num) {
while (k && res.size() && res.back() > c) {
res.pop_back();
--k;
}
res.push_back(c);
}
res.resize(keep);
while (!res.empty() && res[] == '') res.erase(res.begin());
return res.empty() ? "" : res;
}
};

下面这种方法写法稍稍不同,在将数字c加入结果 res 的时候提前做一个判断,假如此时 res 不为空或者数字c不是0,那么才将c加入结果 res 中,这样就避免了 leading zero。for 循环结束后,不是将结果 resize,而是用一个 while 循环,假如此时 k 还大于0,则将 res 末尾移除k个字符即可,参见代码如下:

解法二:

class Solution {
public:
string removeKdigits(string num, int k) {
string res;
int n = num.size(), keep = n - k;
for (char c : num) {
while (k && res.size() && res.back() > c) {
res.pop_back();
--k;
}
if (res.size() || c != '') res.push_back(c);
}
while (res.size() && k--) res.pop_back();
return res.empty() ? "" : res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/402

类似题目:

Create Maximum Number

Remove Duplicate Letters

参考资料:

https://leetcode.com/problems/remove-k-digits/

https://leetcode.com/problems/remove-k-digits/discuss/88708/Straightforward-Java-Solution-Using-Stack

https://leetcode.com/problems/remove-k-digits/discuss/88743/C%2B%2B-6ms-10-lines-solution-with-comments

https://leetcode.com/problems/remove-k-digits/discuss/88660/A-greedy-method-using-stack-O(n)-time-and-O(n)-space

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 402. Remove K Digits 去掉K位数字的更多相关文章

  1. [LeetCode] Remove K Digits 去掉K位数字

    Given a non-negative integer num represented as a string, remove k digits from the number so that th ...

  2. E - Leading and Trailing 求n^k得前三位数字以及后三位数字,保证一定至少存在六位。

    /** 题目:E - Leading and Trailing 链接:https://vjudge.net/contest/154246#problem/E 题意:求n^k得前三位数字以及后三位数字, ...

  3. leetcode 402. Remove K Digits 、321. Create Maximum Number

    402. Remove K Digits https://www.cnblogs.com/grandyang/p/5883736.html https://blog.csdn.net/fuxuemin ...

  4. leetcode 402. Remove K Digits

    Given a non-negative integer num represented as a string, remove k digits from the number so that th ...

  5. LeetCode(60): 第k个排列

    Medium! 题目描述: 给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列. 按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下: "123" ...

  6. 【LeetCode】402. Remove K Digits 解题报告(Python)

    [LeetCode]402. Remove K Digits 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http: ...

  7. 402 Remove K Digits 移掉K位数字

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小.注意:    num 的长度小于 10002 且 ≥ k.    num 不会包含任何前导零.示例 1 :输入: ...

  8. 402. Remove K Digits

    (English version is after the code part) 这个题做起来比看起来容易,然后我也没仔细想,先速度刷完,以后再看有没有改进. 用这个来说: 1 2 4 3 2 2 1 ...

  9. [Swift]LeetCode402. 移掉K位数字 | Remove K Digits

    Given a non-negative integer num represented as a string, remove k digits from the number so that th ...

随机推荐

  1. mysql id 自增实现

    1.在mysql中建表 2.使用: >insert into 表名 values(id,'www',66); 连续运行5次后结果: =============================== ...

  2. 现代WEB前端的性能优化

    现代WEB前端的性能优化 前言:这只是一份学习笔记. 什么是WEB前端 潜在的优化点: DNS是否可以通过缓存减少DNS查询时间? 网络请求的过程走最近的网络环境? 相同的静态资源是否可以缓存? 能否 ...

  3. 坑爹的京东E卡(京东E卡的正确使用方式)

      前言    今年中秋公司发了200的京东E卡(下面简称礼品卡,京东简称jd)这让喜欢在jd自营购买商品的我很是开心,    兴致勃勃打开官网,当我选好商品准备结算时却发现礼品卡无法使用.    后 ...

  4. Go命令行—compile

    常用作编译命令行指定的单个go源码包.会生成一个以文件.o为后缀的目标文件,其文件名与包内第一个源文件的文件名相同. 目标文件可以与其他对象组合成一个包档案或直接传递给链接器(go tool link ...

  5. 重温CLR(十八) 运行时序列化

    序列化是将对象或对象图转换成字节流的过程,反序列化是将字节流转换回对象图的过程.在对象和字节流之间转换是很有用的机制. 1 应用程序的状态(对象图)可轻松保存到磁盘文件或数据库中,并在应用程序下次运行 ...

  6. asp.net发布后其他电脑部署——未能加载文件或程序集 System.Web.Mvc, Version=2.0.0.0, Culture=neutral,

    本机测试及发布使用正常 在项目中添加了引用但相关dll文件未在bin文件夹中 导致发布后部署其他电脑未能加载程序集 网上说要下载相关内容在部署服务器安装 但怕在服务器安装出现其他问题 所以在项目中重新 ...

  7. 2019 梆梆安全java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.梆梆安全等公司offer,岗位是Java后端开发,因为发展原因最终选择去了梆梆安全,入职一年时间了,也成为了面 ...

  8. Java自学-I/O 对象流

    Java 对象流 ObjectInputStream,ObjectOutputStream 对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘 一个对象以流的形式进行传输,叫做序列化. ...

  9. placeholder和assign速度对比

    在CPU上,使用variable和placeholder效果差不多 在GPU上,使用variable要比每次都传placeholder快得多3:2 使用GPU的瓶颈主要在于GPU和内存之间的复制操作 ...

  10. 在使用 Fortify进行源码扫描时需要做对项目需要做什么?

    1.一般我们的项目都是svn 或git 进行管理的,为了扫出异常的问题 做好把   “” .svn    “”  文件删除 2.把我们的项目需要的jar 文件放到一个文件夹内同项目一起进行扫描.这样为 ...