LintCode 182. 删除数字

182. 删除数字

给出一个字符串 A, 表示一个 n 位正整数, 删除其中 k 位数字, 使得剩余的数字仍然按照原来的顺序排列产生一个新的正整数。

找到删除 k 个数字之后的最小正整数。

N <= 240, k <= N

样例
给出一个字符串代表的正整数 A 和一个整数 k, 其中 A = 178542, k = 4

返回一个字符串 "12"


思路:删去数字使得最后剩余的数字最小,相当于从当前数字里面找到相应个数数字使之最小,可以使用贪心思想
从前往后找第一个最小值使之成为找到的数的第一个数字,需要注意的是为了保证后面仍然存在足够多的数用来选择,查找
的区间是有限的是从[start,A.size()-count]这样一个区间里,每当找到这样一个数,剩余数的查找范围相应也就缩短了
然后依次递归找到一系列数

 

写法1:没通过,这道题对于第一个数是可以为0的,我的写法是第一个数排除0的写法

class Solution {
public:
    /**
     * @param A: A positive integer which has N digits, A is a string
     * @param k: Remove k digits
     * @return: A string
     */
    string DeleteDigits(string &A, int k) {
        // write your code here
        int size = A.size();
        if(size <= k) return 0;
        int index = k;
        for(int i = k; i>=0; --i){
            if(A[i]<=A[index] && A[i]!='0') index = i;
        }
        string res = "";
        res.push_back(A[index]);
        string r = MinNum(A,index+1,size-k-1);
        if(r == "-1") return res; 
        return res+r;
    }
    
    string MinNum(string &A, int start, int count){
        if(count == 0) return "-1";
        int index = A.size()-count;
        for(int i = A.size()-count; i>=start; --i){
            if(A[i]<=A[index]) index = i;
        }
        string res = "";
        res.push_back(A[index]);
        string r = MinNum(A,index+1,count-1);
        if(r == "-1") return res; 
        return res+r;
    }
};

  写法2:通过,思路和上面相同,唯一需要的就是对最后得到的string做一下头部去0

class Solution {
public:
    /**
     * @param A: A positive integer which has N digits, A is a string
     * @param k: Remove k digits
     * @return: A string
     */
    string DeleteDigits(string &A, int k) {
        // write your code here
        int size = A.size();
        if(size <= k) return "0";
        string r = MinNum(A,0,size-k);
        int index = 0;
        for(;index<r.size();++index){//头部去0操作
        	if(r[index]!='0') break;
        }
        return r.substr(index);//substr用法:substr(m,n)从m位置开始取n个字符;substr(m)从第m个字符截取到末尾
    }
    
    string MinNum(string &A, int start, int count){//start表示每次取到数字之后下一个数字取值范围的起点,count表示仍然需要取得数字个数
        if(count == 0) return "-1";//迭代出口
        int index = A.size()-count;
        for(int i = A.size()-count; i>=start; --i){//在这个范围里面取第一个最小值
            if(A[i]<=A[index]) index = i;
        }
        string res = "";
        res.push_back(A[index]);
        string r = MinNum(A,index+1,count-1);//递归
        if(r == "-1") return res; //迭代出口特殊处理
        return res+r;
    }
};

  好像只要写个循环就可以了,没必要用递归。。。算了,思想懂了应该就问题不大。

转载于:https://www.cnblogs.com/J1ac/p/8797956.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值