algorithm-base/animation-simulation/栈和队列/leetcode402移掉K位数字.md
2021-03-20 16:57:12 +08:00

97 lines
4.5 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

> 如果阅读时发现错误或者动画不可以显示的问题可以添加我微信好友 **[tan45du_one](https://raw.githubusercontent.com/tan45du/tan45du.github.io/master/个人微信.15egrcgqd94w.jpg)** ,备注 github + 题目 + 问题 向我反馈
>
> 感谢支持该仓库会一直维护希望对各位有一丢丢帮助
>
> 另外希望手机阅读的同学可以来我的 <u>[**公众号袁厨的算法小屋**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u> 两个平台同步,想要和题友一起刷题,互相监督的同学,可以在我的小屋点击<u>[**刷题小队**](https://raw.githubusercontent.com/tan45du/test/master/微信图片_20210320152235.2pthdebvh1c0.png)</u>进入。
#### [402. 移掉K位数字](https://leetcode-cn.com/problems/remove-k-digits/)
今天给大家带来一个栈的中等题目移掉K位数字题目很简单但是很有趣另外明天继续给大家带来一道栈和队列题目困难那么咱们的栈和队列模块就结束啦下周开始整字符串的题目啦
### 题目描述
给定一个以字符串表示的非负整数 num移除这个数中的 k 位数字使得剩下的数字最小
注意:
> num 的长度小于 10002 k
> num 不会包含任何前导零
示例 1 :
> 输入: num = "1432219", k = 3
> 输出: "1219"
> 解释: 移除掉三个数字 4, 3, 2 形成一个新的最小的数字 1219
示例 2 :
> 输入: num = "10200", k = 1
> 输出: "200"
> 解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零
示例 3 :
> 输入: num = "10", k = 2
> 输出: "0"
> 解释: 从原数字移除所有的数字剩余为空就是0
题目很容易理解而且也很容易实现因为在示例中几乎把所有特殊情况都进行了举例我们直接代码实现就好啦
### 贪心
下面我们来看一下用栈的解题思路因为我们需要删除掉K位数字得到最小值那么我们需要注意的是删除的数字应该尽量在高位则当前位小于前一位时对前一位出栈当前位入栈大家思考一下思路是不是这样呢
另外我们需要注意的是仅删除K位数字得到最小值比如54321我们删除3位得到21但是刚才我们说当前位小于前一位时则前一位出栈当前位入栈所以我们需要加上删除K位的规则
废话不多说我们直接上动图把该题吃透
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210320141440557.gif)
PPT中的文字
> 这里需要注意的是我们不需要将0入栈因为0如果处于栈底没有比它更小的值所以它不会被移除我们只有在最后才有机会处理它因为我们的010 = 10 首位0是需要在最后去掉的所以我们这里可以直接不让其入栈continue掉这次循环也不改变K值这样我们最后出栈处理时就不用考虑啦这样逻辑就比官方题解好理解一些也简洁一些
> 这里需要注意的是我们的K值还为2我们目前仅删除2位数字但是我们需要删除4位但是后面的几位都是当前位大于前一位所以我们需要在遍历结束后再移除后面最大的两位数字
```java
class Solution {
public String removeKdigits(String num, int k) {
//特殊情况全部删除
if (num.length() == k) {
return "0";
}
char[] s = num.toCharArray();
Stack<Character> stack = new Stack<>();
//遍历数组
for (Character i : s) {
//移除元素的情况k--
while (!stack.isEmpty() && i < stack.peek() && k > 0) {
stack.pop();
k--;
}
//栈为空且当前位为0时我们不需要将其入栈
if (stack.isEmpty() && i == '0') {
continue;
}
stack.push(i);
}
while (k > 0) {
stack.pop();
k--;
}
if (stack.isEmpty()) {
return "0";
}
//反转并返回字符串
StringBuilder str = new StringBuilder();
while (!stack.isEmpty()) {
str.append(stack.pop());
}
return str.reverse().toString();
}
}
```
这个题目也是很不错的题目是精心挑选的然后动图里面的例子也是精心构思过的所以大家记得打卡呀