algorithm-base/animation-simulation/栈和队列/移除K位数字.md

92 lines
3.8 KiB
Markdown
Raw Normal View History

2021-03-19 10:50:39 +00:00
# 移除K位数字
今天给大家带来一个栈的中等题目移掉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位的规则。
废话不多说我们直接上动图,把该题吃透!
![移除K位数字](E:\Typora笔记\CSDN\leetcode通关笔记\博客动图\移除K位数字.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--;
}
//这个是最后栈为空时删除一位比如我们的10删除一位为0按上面逻辑我们会返回"",所以我们让其返回"0"
if (stack.isEmpty()) {
return "0";
}
//反转并返回字符串
StringBuilder str = new StringBuilder();
while (!stack.isEmpty()) {
str.append(stack.pop());
}
return str.reverse().toString();
}
}
```
这个题目也是很不错的,题目是精心挑选的,然后动图里面的例子也是精心构思过的。所以大家记得打卡呀!