402.移掉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位数字,那么就能计算出剩下的数字的数量(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

原文地址:https://www.cnblogs.com/Jiewl/p/12748167.html