LeetCode 402. 移掉K位数字 单调栈/medium


1.Description

给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

注意:

num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。


2.Example

示例 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

3.Solution

1.直接写

使用nums数组储存原字符串num中各个数字出现的次数,并将各个数字出现的位置以队列的形式存在hashmap里。最后取出num.length()-k个数字组成答案字符串就行了(取得时候按从0到9依次看出现的位置是否合适,用position保存位置信息),注意最后要去掉前缀0。

class Solution {
	public String removeKdigits(String num, int k) {
    	int len = num.length()-k;
    	String res = "";
    	int position = -1;
    	
        if(num.length()==k){
            return "0";
        }

    	int[] nums = new int[10];
    	Map<Integer, Deque<Integer>> hashMap = new HashMap<Integer, Deque<Integer>>();
    	for(int i=0;i<num.length();i++) {
    		int count = num.charAt(i)-'0';
    		nums[count]++;
    		if(!hashMap.containsKey(count)) {
    			Deque<Integer> list = new ArrayDeque<Integer>();
    			list.addLast(i);
    			hashMap.put(count, list);
    		}else {
    			Deque<Integer> list = new ArrayDeque<Integer>(hashMap.get(count));
    			list.addLast(i);
    			hashMap.put(count, list);
    		}
    	}
    	
    	for(int i=0;i<len;i++) {
    		//num.length()-(len-i) -> k+i
    		for(int j=0;j<10;j++) {
				if(hashMap.containsKey(j)&&!hashMap.get(j).isEmpty()&&hashMap.get(j).peekFirst()<k+i+1&&hashMap.get(j).peekFirst()>position) {
					res += num.charAt(hashMap.get(j).peekFirst());
					position = hashMap.get(j).peekFirst();
					hashMap.get(j).removeFirst();
					break;
				}else if(hashMap.containsKey(j)&&!hashMap.get(j).isEmpty()&&hashMap.get(j).peekFirst()<k+i+1&&hashMap.get(j).peekFirst()<position) {
					hashMap.get(j).removeFirst();
					j--;
				}
			}
    	}
    	while(res.startsWith("0")) {
    		if(res.length()==1) {
    			res = "0";
    			break;
    		}
    		res = res.substring(1, res.length());
    	}
    	return res;
    }
}

2.使用单调栈

「手画图解」单调递增栈,为什么?何时用?| 402.移掉K位数字

class Solution {
    public String removeKdigits(String num, int k) {
        Deque<Character> stack = new ArrayDeque<>(num.length());
        for(char c : num.toCharArray()){
            while(k > 0 && !stack.isEmpty() && c < stack.peek()){
                stack.pop();
                k--;
            }
            if( c != '0' || !stack.isEmpty()){
            stack.push(c);
            
            }
        }

        while( k > 0 && !stack.isEmpty()){
            stack.pop();
            k--;
        }

        StringBuffer buffer = new StringBuffer();
        while(!stack.isEmpty()){
            buffer.append(stack.pollLast());
        }
        
        return buffer.length() == 0 ? "0" : buffer.toString();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值