一【题目类别】
- 栈
二【题目难度】
- 中等
三【题目编号】
- 402.移掉 K 位数字
四【题目描述】
- 给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
五【题目示例】
-
示例 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 。
六【题目提示】
- 1 < = k < = n u m . l e n g t h < = 1 0 5 1 <= k <= num.length <= 10^5 1<=k<=num.length<=105
- num 仅由若干位数字(0 - 9)组成
- 除了 0 本身之外,num 不含任何前导零
七【解题思路】
- 利用单调栈+贪心的思想
- 因为要保证最小,所以每次我们都要比较相邻两位谁更小,小的做高位,越小越好,这也就是贪心的思想
- 还有k是要我们删除的数字个数,如果维护单调栈的过程中,还没达到要求删除的元素个数,将后面的元素弹出栈即可,有人可能会问,为什么不弹出前面的?因为前面的已经是维护的单调栈,肯定是保证的最小的高位,如果删除前面的,高位就变大了,也就没办法保证最小了
- 最后再判断如果结果长度为0,返回(字符/字符串)0
- 如果结果长度不为0,返回结果即可
八【时间频度】
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组元素个数
- 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组元素个数
九【代码实现】
- Java语言版
package Stack;
import java.util.Deque;
import java.util.LinkedList;
public class p402_RemoveKDigits {
public static void main(String[] args) {
String num = "1432219";
int k = 3;
String res = removeKdigits(num, k);
System.out.println("res = " + res);
}
public static String removeKdigits(String num, int k) {
Deque<Character> stack = new LinkedList<Character>();
int len = num.length();
for (int i = 0; i < len; i++) {
char digit = num.charAt(i);
while (!stack.isEmpty() && stack.peekLast() > digit && k > 0) {
stack.pollLast();
k--;
}
stack.offerLast(digit);
}
for (int i = 0; i < k; i++) {
stack.pollLast();
}
StringBuilder res = new StringBuilder();
boolean isLeadingZero = true;
while (!stack.isEmpty()) {
char digit = stack.pollFirst();
if (isLeadingZero && digit == '0') {
continue;
}
isLeadingZero = false;
res.append(digit);
}
return res.length() == 0 ? "0" : res.toString();
}
}
- C语言版
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
char * removeKdigits(char * num, int k)
{
int len = strlen(num);
char* stack = (char*)malloc(sizeof(char) * (len + 1));
int top = 0;
for (int i = 0; i < len; i++)
{
while (top > 0 && stack[top] > num[i] && k)
{
top--;
k--;
}
stack[++top] = num[i];
}
top -= k;
char* res = (char*)malloc(sizeof(char) * (len + 1));
int resIndex = 0;
bool isLeadingZero = true;
for (int i = 1; i <= top; i++)
{
if (isLeadingZero && stack[i] == '0')
{
continue;
}
isLeadingZero = false;
res[resIndex++] = stack[i];
}
if (resIndex == 0)
{
res[0] = '0', res[1] = '\0';
}
else
{
res[resIndex] = '\0';
}
return res;
}
/*主函数省略*/
十【提交结果】
-
Java语言版
-
C语言版