LeetCode402-移掉K位数字

LeetCode402-移掉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。

一、思路

(一)贪心算法

一个很明显的移除方法是找出所有的:
n u m [ i ] > n u m [ i + 1 ] num[i]>num[i + 1] num[i]>num[i+1]
删除num[i+1]

也就是说:前一个(高位)数比后一个(低位)数要更大,则删除前一个(高位)数。这个想法很好理解,就是使用更小的数字去取代原来的高位数字,这么一来num的数值就变小了。

我们假设k足够大,反复执行该操作,会使得num变成一个非递减数,也就是说其中的数字从高位到低位是非递减的。

对于非递减数num,我们需要做的是不断移除num中最大的数字,因为该数是非递减的,所以最大的数字一定是在最后面。

最后,删除前导0,判断num是否为空就行了。

1、将num变为非递减数

非递减数:“123455567899”
递增数:“123456789”

有两种情况:

  • k不足够大。假设num至少需要删除n个数,才能变为非递减数,而n > k,那么我们至少要让num的前面部分变为非递减的
  • k足够大。直接将之变为非递减数。

代码:

		for (int i = 1; i < num.size(); i++) {
			while (k && i >= 1 && num[i] < num[i - 1]) {
				num.erase(i - 1, 1);
				i--;
				k--;
			}
		}
2、对于非递减数的处理

从末位开始删除数字,直到k=0为止

综合以上两点,代码:

class Solution {
public:
	string removeKdigits(string num, int k) {
		if (k >= num.size())
			return "0";

		for (int i = 1; i < num.size(); i++) {
			while (k && i >= 1 && num[i] < num[i - 1]) {
				num.erase(i - 1, 1);
				i--;
				k--;
			}
		}

		while (k) {
			num.pop_back();
			k--;
		}

		while (num.size() && num[0] == '0'){
			num.erase(0, 1);
		}

		return num.empty() ? "0" : num;
	}
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值