删除k个数字后,保留最小的数

介绍

如:1593121212去掉3个数,剩下1121212最小。
思路如下:
删除k个,可以采用贪心算法,每次删除1个
那么每次删哪一个呢?

若N<2,那就不用纠结了,因为最多只有一个选择
若N>=2,则该整数可以写成XabY,X,Y分别是前缀和后缀,长度可以为0. a,b是相邻的两个数字,且a在b的左边。我们面临的选择就是删除a还是删除b的问题。若删除a,删除后变为XbY; 若删除b,删除后变为XaY.
(1) 若a≠ \ne 
̸
​    
 =b,为了让剩下的部分最小,显然我们应该倾向于把a,b中的较大者删掉. 即若a<b, 倾向于删除b; 若a>b,倾向于删除a.
(2) 若a=b, 删除a和删除b是等价的,我们跳过a,比较b和它的后继,又变成问题(1)了。
此时我们已经能看出:
要求剩下的数字最小,从左向右扫描,找出连续的非严格递增串,删除最后一个

要求剩下的数字最大,从左向右扫描,找出连续的非严格递减串,删除最后一个。


实现:

public static String removeKdigits(String num, int k) {
		if(k >= num.length())
			return "0";
		
		int newLength = num.length() - k;

		char[] stack = new char[num.length()];

		int top = 0;

		for (int i = 0; i < num.length(); ++i) {
			char c = num.charAt(i);

			while (top > 0 && stack[top - 1] > c && k > 0) {
				top -= 1;
				k -= 1;
			}

			stack[top++] = c;

		}

		int offest = 0;
		while (offest < newLength && stack[offest] == '0') {
			offest++;
		}

		return offest == newLength ? "0" : new String(stack, offest, newLength - offest);

	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值