给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。
注意:
- num 的长度小于 10002 且 ≥ k。
- num 不会包含任何前导零。
示例 1 :
输入: num = "1432219", k = 3 输出: "1219" 解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。
示例 2 :
输入: num = "10200", k = 1 输出: "200" 解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
示例 3 :
输入: num = "10", k = 2 输出: "0" 解释: 从原数字移除所有的数字,剩余为空就是0。
思路分析:(1)首先分析当k的值小于0或者k的值大于给定字符串的长度时,返回给定字符串
(2)当给定字符串的长度和k值相等时返回“0”
(3)除以上两种特殊情况则有如下分析:
a.我们为了得到一个较小的序列,需要从高位出发,如果下一位数字比当前的数字小,并且删除的次数k还没使用完的话,就删除当前的数字,接着继续向前比较,最后会得到一个较小的序列。
b.具体实现:由于字符可以直接比较大小,故我们可以选用一个char类型的数组stack作为栈,并且维持该栈的升序规则,用top作为栈顶,如果当前元素小于栈顶元素,则栈顶元素出栈(即top--),否则将当前元素压栈(即stack[top++]=当前字符)。
注意:由于可能是0开头的字符数组,故需要统一改字符数组开头的0的个数count.
最后配合String类的一个构造函数
String(char[] value, int offset, int count) 分配一个新的 String ,它包含取自字符数组参数一个子数组的字符。 |
即可得到目标字符串。
class Solution {
public String removeKdigits(String num, int k) {
if(k<=0 ||k > num.length()){ //如果k<0,返回空
return num;
}
if(num.length()==k){//如果
return "0";
}
//定义一个字符数组模拟栈
char[] stack=new char[num.length()];
//定义一个栈顶标志
int top=0;
//记录除k位之外的位数
int weishu=num.length()-k;
//遍历输入的字符串
for(int i=0;i<num.length();i++){
char cur=num.charAt(i);//获取当前字符
while(top>0 && cur<stack[top-1] && k>0){//当前字符小于栈顶元素时,栈顶元素出栈
top--;//将栈顶元素出栈
k--;//更新次数
}
stack[top++]=cur; //当前字符入栈并更新栈顶标志
}
//统计开头为0的个数
int count=0;
for(int i=0;i<stack.length;i++){
if(stack[i]!='0'){
break;
}else{
count++;
}
}
//返回目标字符串
return count==weishu?"0":new String(stack,count,weishu-count);
}
}