C++ 【贪心】以栈优化的形式移除K个数字后最小

移除K个数字

题目

已知一个使用字符串表示的非负整数num,将num中的K个数字移除,求移除K个数字后,可以获得的最小的可能的新数字。
例如:
输入:num = “1432219”,k = 3
去除3个数字后得到的很多可能里,如1432、4322、2219、1219、1229…;其中以去掉数字4、3、2得到的1219最小!

思路

因为越高位的数字决定的大小比低位更有效,所以如果要最小的数字,需要尽可能让新数字优先最高位最小,次高位最小,次次高位最小…最终直到移除够K个数字

建立一个数字字符栈,从字符串开头开始,按顺序压入栈中,当k仍然>0时,且新遍历的数字字符如果比栈顶元素大则不放入栈中,即移除该数字字符,若不大于栈顶元素,则放入到栈中保留,直至移除够K个数字后,将还未放入的数字字符全部放入栈中,则达到了使越高位(越接近栈底)的数字越小,最终数字最小

当然还考虑到数字中有0出现时,应该有怎样的特殊处理?
例如:num = 100200,k=1时。
应该去除1,因为它比0大,然后因为栈为空,高位的数字为0无意义,所以不放入栈中,最终结果为200,其为最小。

最后就是将栈中储存的数字字符储存为字符串并返回:
按找倒着的顺序,将栈顶元素放在字符串末尾(S.size()-1),形成字符串返回。

过程如图所示:


代码如下:

#include <stdio.h>
#include <string>
#include <stack>
class Solution {
public:
    std::string removeKdigits(std::string num, int k) {
    	std::stack<int> S;
    	std::string result = "";
    	for (int i = 0; i < num.length(); i++){
	    	int number = num[i] - '0';
	    	while(S.size() != 0 && S[S.size()-1] > number && k > 0){
	    		S.pop();
	    		k--;
	    	}
	    	if (number != 0 || S.size() != 0){
	    		S.push(number);
	    	}
	    }
	    while(S.size() != 0 && k > 0){
    		S.pop();
    		k--;
    	}
	    for (int i = S.size() - 1; i >= 0; i--){
    		result[i] = S.top();
    		S.pop();
    	}
    	if (result == ""){
	    	result = "0";
	    }
    	return result;
    }
};

致谢

本章知识点和思路由小象学院相关视频提供,由本人学习并梳理得出,希望自己加深记忆的同时,也能给大家提供更多有关于一些算法的知识点。
你的点赞、评论、收藏就是对我最大的支持与鼓励,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值