402. 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.

Note:

  • The length of num is less than 10002 and will be ≥ k.
  • The given num does not contain any leading zero.

Example 1:

Input: num = "1432219", k = 3
Output: "1219"
Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.

Example 2:

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.

Example 3:

Input: num = "10", k = 2
Output: "0"
Explanation: Remove all the digits from the number and it is left with nothing which is 0.


思路:怎样才能让结果最小呢?从前面开始,发现小的数字就应该把前面的数字替换掉,有个明显的出栈入栈的过程,于是乎用栈,那能确保怎样替换是正确的结果吗?仔细想想发现其实这就是greedy algorithm,是可以得到正确的结果的


/*
 * greedy algorithm using stack
 * 每一步都是到目前为止最优的结果(不管后面是什么)),谓之贪心
 * 后一步的最优结果一定一前面的最优结果为基础
 */
public class Solution {
    public String removeKdigits(String num, int k) {
    	if(num.length() == k)	return "0";
    	Stack stack = new Stack();
    	char[] cs = num.toCharArray();
    	int cnt = k;
    	
    	for(char c : cs) {
    		while(!stack.isEmpty() && stack.peek()>c && cnt>0) {
    			stack.pop();
    			cnt --;
    		}
    		stack.push(c);
    	}
    	StringBuilder sb = new StringBuilder();
    	while(!stack.isEmpty())		sb.append(stack.pop());
    	
    	//delete 0 from end
    	while(sb.length()>0 && sb.charAt(sb.length()-1) == '0')	
    		sb.deleteCharAt(sb.length()-1);
    	
    	int maxLen = Math.min(num.length()-k, sb.length());
		return sb.length()==0 ? "0" : sb.reverse().substring(0, maxLen).toString();
    }
}



二刷:

直观感觉贪心,策略是尽可能把小的数放到高位上,最佳的情况就是从左到右都是递增的,

但是如果不是呢?某一位比前面的数小,那我们可以肯定是要删除前面大的树,让这个更小的数往前面靠,

考虑到前面数是升序的,所以删除就是从后往前删,这不就是单调栈嘛

你可能感兴趣的:(leetcode)