LeetCode-Remove K Digits

题目 Remove K Digits

Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

Note:
The length of num is less than 10002 and will be ≥ k.
The given num does not contain any leading zero.

即给定一个非负数值字符串,要求删除k个字符的情况下数值最小。

测试例子

Example 1

Input: num = “1432219”, k = 3
Output: “1219”
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.

Example 2

Input: num = “10200”, k = 1
Output: “200”
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.

代码

第一版本
/*************************************************************************
    > File Name: Solution.cpp
    > Author: Duke-wei
    > Mail: 13540639584@163.com 
    > Created Time: 2017年10月13日 星期五 15时12分09秒
 ************************************************************************/

#include<iostream>
#include<string>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
class Solution1{
public:
    //首先简化问题,考虑一次去除一个字符的情况,然后去除k次
    string removeKdigits(string num, int k) {
        if(k==num.size()) return "0";
        for(int i=0;i<k;++i){
            if(num.size()<=1) return "0";
            num = removeone(num);
            //去掉头部0
            int j = 0;
            for(;j<num.size()&&num[j]=='0';++j);
            num = num.substr(j);
        }
        if(num.size()==0) return "0";
        return num;
    }
    //一次去除一个字符,通过找规律发现
    //去除一个字符,即开头非递减序列的最后一个
    //如1354278 即去除5,5是首个开始递减的字符
    //如12477589 去除7
    //如7511 去除7
    string removeone(string& s){
        int i = 0;
        for(;i<s.size()-1;++i){
            if(s[i]>s[i+1]) break;
        }
        string ret = s.substr(0,i);
        ret += s.substr(i+1);
        return ret;
    }
};
第二版本

每次删除一个肯定很慢,所有要遍历一次删除k个,发现这k个字符的规律,就可以通过栈来实现删除,从头入栈,发现比栈顶小,则弹出栈顶,即去除一个字符。

class Solution2{
    public:
    string removeKdigits(string num, int k) {
        if(k==num.size()) return "0";
        stack<char> sc;
        int i=0;
        while(k>0){
            if(i>=num.size()){
                sc.pop();
                --k;
            }else if(sc.empty()||sc.top()<=num[i]){
                sc.push(num[i++]);
            }else{
                sc.pop();
                --k;
            }
        }
        while(i<num.size()) sc.push(num[i++]);
        string ret;
        while(!sc.empty()){
            ret.push_back(sc.top());
            sc.pop();
        }
        reverse(ret.begin(),ret.end());
        i=0;
        while(i<ret.size()&&ret[i]=='0')++i;
        if(i==ret.size()) return "0";
        return ret.substr(i);
    }
};
第三版本

简化代码,看了大神的代码,简洁,直接用striing替换stack的功能。

class Solution3{
    public:
    string removeKdigits(string num, int k) {
        string ans = "";                                         // treat ans as a stack in below for loop
        for (char c : num) {
            while (ans.length() && ans.back() > c && k) {
                ans.pop_back();                                  // make sure digits in ans are in ascending order
                k--;                                             // remove one char
            }
            if (ans.length() || c != '0') { ans.push_back(c); }  // can't have leading '0'
        }
        while (ans.length() && k--) { ans.pop_back(); }          // make sure remove k digits in total
        return ans.empty() ? "0" : ans;
    }
};

思考扩展

  • 这题明确了该字符串是非负数值,因此如果数值为负则应该怎么处理?
  • 如果要求去除k个后是最大怎么处理?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值