remove digits删除数字

27 篇文章 0 订阅
2 篇文章 0 订阅

问题描述:给定存为string形式的非负整数num,从中删除k位数字,得到新数字,并满足此结果是可能产生的最小数字。

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.

参考:

c++版本思路+代码:https://www.cnblogs.com/grandyang/p/5883736.html

java版本思路+代码:https://www.jianshu.com/p/7ed3ecab86f5

思路:

(1)采用栈结构和贪心算法。栈中保存最终的结果数字序列,并保持近似单调递增的结构(只删除k个数字)。

(2)依次按照从高位到低位的顺序读入原数字,如果当前位数字较小(小于栈顶元素,且删除的数字总数还不到k,栈不为空),则依次将栈顶元素出栈删除。如果当前位数字较大或者删除了足够多位(k)的数字或栈为空,则将当前位数字入栈。

(3)如果没有在前一个循环中删除足够多位的数字,则依次将栈顶元素出栈删除。然后删掉最终结果的前置0,返回结果。

代码:

class Solution {
public:
    /**
     * @param num: a number
     * @param k: the k digits
     * @return: the smallest number
     */
    string removeKdigits(string &num, int k) {
        // write your code here.
        int n = num.size();
        if (!num.compare("0") || k < 1) {
            return num;
        }
        if (n==k) return "0";
        int keep = n-k;
        stack<char> st;
        for (char c : num) {
            while (!st.empty() && k > 0 && st.top() > c){
            	st.pop();
                --k;
            }
            //if (st.empty() && c == '0') {
            //    continue; //leading zeros
            //}
            st.push(c);
        }
        while(!st.empty() && k-- >0) {
        	st.pop();
        }
        string res;
        int st_r = keep;
        while (st_r-- > 0) {
        	char t = st.top();
        	st.pop();
        	//res.insert(0,to_string(t));
        	stringstream ss;
        	ss << t;
        	string t2 = ss.str();
        	res.insert(0,t2);
        }
        int dz = 0; //delete leading zeros;
        for (int i = 0; i < keep; i++) {
            if (res[i]=='0') {
                dz++;
            } 
            else break;
        }
        if (dz>0) res.erase(0,dz);
        return res.empty() ? "0": res;
    }
};

参考第一个链接中的代码更简洁。没有定义stack,直接利用了string类型保存最终的结果数据,并进行类似的操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值