给定一个以字符串表示的非负整数 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位数字,那么就能计算出剩下的数字的数量(len)。那么我们就来计算什么样的数需要保留。
首先从字符串头部开始,是越小越好,但是每个选择的范围不是num整个字符串(设num长度为nlen),而是[0,nlen - len],这是第一个字符的寻找范围,假设找到的位置是i,此时nlen = nlen - i,len = len - 1,那么第二个字符的寻找范围就是[i,nlen - len],每次使用nlen都要重新赋值,就这样可以把每个需要的数字给计算出来,再添加要需要返回的字符串中,再去掉开始的零.
class Solution {
public String removeKdigits(String num, int k) {
if(num.length() == k) {
return "0";
}
char[] cs = num.toCharArray();
StringBuilder str = new StringBuilder();
int nlen = cs.length;
int len = nlen - k; //需要留下的数的个数
char c = '9'; //用来求范围内的最小值
int i = 0;
while(len > 0) {
int start = i; //每次找数的起点
int end = nlen - len; //每次找数的终点
for(; i <= end; i++) {
c = (char) Math.min(c, cs[i]);
}
str.append(c);
i = num.indexOf(c, start); //找到的当前的最小值的位置
c = '9';
len --;
i++;
}
String string = str.toString();
while(string.charAt(0) == '0' && string.length() > 1) {
string = string.substring(1);
}
return string;
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-k-digits