LeetCode402 Remove K Digits

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.
example:
Input: num = “10200”, k = 1
Output: “200”
Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.

well, I used to have no idea how such problem can be solved.
but now I know it is a mono stack related problem.

now the number of digits is sure, so in order to make it as smaller as possible, we only need to delete those that made the remaining digits increase. and if we can’t make all remaining sequence increase, as least we should make that increase sequence as front head as possible. and the starting digits should be as small as possible.
but that didn’t feels right, and the general idea is pretty vague.

the general idea is: we know that digts on the left side matters, so we use a stack and push each of chars in that stack. whenever meet a digit which is less than the previous digit, discard the previous one. so that means we will use stack to maintain a increasing sequence.
and that makes the subsequence the smallest given a certain length.

public class Solution {
    public String removeKdigits(String num, int k) {
        int len = num.length();
        //corner case
        if(k==len)        
            return "0";
            
        Stack<Character> stack = new Stack<>();
        int i =0;
        //the following two whiles are the classic monotonic stack
        while(i<num.length()){
            //whenever meet a digit which is less than the previous digit, discard the previous one
            while(k>0 && !stack.isEmpty() && stack.peek()>num.charAt(i)){
                stack.pop();
                k--;
            }
            stack.push(num.charAt(i));
            i++;
        }
        
        // corner case like "1111"
        //if you pay attention to previous code, then you will find out that situations like"1111" is a concer case, because after we construct the monotonic stack, k doesn;t necessarly be the length of required, it is just a subsequence of increasing chars. so we only get the first (num.length-k) element in this sequence will do.
        while(k>0){ 
            stack.pop();
            k--;            
        }
        
        //construct the number from the stack
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty())
            sb.append(stack.pop());
        
        //remove all the 0 at the head
        while(sb.length()>1 && sb.charAt(sb.length() - 1)=='0')
            sb.deleteCharAt(sb.length() - 1);
        return sb.reverse().toString();
    }
}
posted @ 2020-05-31 09:51  EvanMeetTheWorld  阅读(8)  评论(0)    收藏  举报