问题描述:给定存为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类型保存最终的结果数据,并进行类似的操作。