https://leetcode.com/problems/remove-k-digits/
https://blog.csdn.net/fuxuemingzhu/article/details/81034522
使用一个栈作为辅助,遍历数字字符串,当当前的字符比栈最后的字符小的时候,说明要把栈的最后的这个字符删除掉。为什么呢?你想,把栈最后的字符删除掉,然后用现在的字符进行替换,是不是数字比以前的那种情况更小了?所以同样的道理,做一个while循环!这个很重要,可是我没有想到。在每一个数字处理的时候,都要做一个循环,使得栈里面最后的数字比当前数字大的都弹出去。
最后,如果K还没用完,那要删除哪里的字符呢?毋庸置疑肯定是最后的字符,因为前面的字符都是小字符。
https://leetcode.com/problems/remove-k-digits/discuss/88675/Clear-Java-Solution-Using-Deque
http://blog.csdn.net/qq508618087/article/details/52584133
https://discuss.leetcode.com/topic/59580/short-10-lines-o-n-java-code
https://discuss.leetcode.com/topic/59412/a-greedy-method-using-stack-o-n-time-and-o-n-space
https://discuss.leetcode.com/topic/59501/6ms-java-solution-with-detailed-comment
这道题让我们将给定的数字去掉k位,要使得留下来的数字最小,这题跟LeetCode上之前那道Create Maximum Number有些类似,可以借鉴其中的思路,如果n是num的长度,我们要去除k个,那么需要剩下n-k个,我们开始遍历给定数字num的每一位,对于当前遍历到的数字c,进行如下while循环,如果res不为空,且k大于0,且res的最后一位大于c,那么我们应该将res的最后一位移去,且k自减1。当跳出while循环后,我们将c加入res中,最后我们将res的大小重设为n-k。根据题目中的描述,可能会出现"0200"这样不符合要求的情况,所以我们用一个while循环来去掉前面的所有0,然后返回时判断是否为空,为空则返回“0”
* 这是一个非常简单的问题,贪心解决法 * 即 removeKdigits(num,k) = removeKdigits(removeKdigits(num,1),k-1) * 进行最多K轮的删除,每次从头开始寻找一位删除: * 1、要么第二位是0,这样相当于至少删了两位,很值得,必须这么做 * 2、不然,找到第一个出现下降转折的位置 删除 * */ public String removeKdigits(String num, int k) { int n; while(true){ n = num.length(); if(n <= k || n == 0) return "0"; if(k-- == 0) return num; if(num.charAt(1) == '0'){ int firstNotZero = 1; while(firstNotZero < num.length() && num.charAt(firstNotZero) == '0') firstNotZero ++; num=num.substring(firstNotZero); } else{ int startIndex = 0; while(startIndex < num.length() - 1 && num.charAt(startIndex) <= num.charAt(startIndex + 1)) startIndex ++; num=num.substring(0,startIndex)+num.substring(startIndex+1); } } }
X.
http://bookshadow.com/weblog/2016/09/18/leetcode-remove-k-digits/
X. https://discuss.leetcode.com/topic/59871/two-algorithms-with-detailed-explaination
http://www.1point3acres.com/bbs/thread-202732-1-1.html
给一个string, 找出lexical order 最小的, size==k的, subsequence, (note, not substring)
String findMin(String s, k){} e.g.
input
s=pineapple, k==3,
output: ale
ale is the lexical order smallest subsequnce of length 3.
我是暴力求解的:
1. find the first occur position of distinct char.
2. then start from that position.
3. dfs to find lenght==3, subsequence(dfs, combination way); . visit 1point3acres.com for more.
4. find the one with smallest lexical order.
我就是说了个大概.
pop的时候需要看后面还剩几个元素了
元素不够的时候就含泪不pop了,直接push进去
比如你说的例子,其实是
f->e->d->c->cb->cba
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.X. Ordered Stack
https://blog.csdn.net/fuxuemingzhu/article/details/81034522
使用一个栈作为辅助,遍历数字字符串,当当前的字符比栈最后的字符小的时候,说明要把栈的最后的这个字符删除掉。为什么呢?你想,把栈最后的字符删除掉,然后用现在的字符进行替换,是不是数字比以前的那种情况更小了?所以同样的道理,做一个while循环!这个很重要,可是我没有想到。在每一个数字处理的时候,都要做一个循环,使得栈里面最后的数字比当前数字大的都弹出去。
最后,如果K还没用完,那要删除哪里的字符呢?毋庸置疑肯定是最后的字符,因为前面的字符都是小字符。
https://leetcode.com/problems/remove-k-digits/discuss/88675/Clear-Java-Solution-Using-Deque
 // the goal is to create an ascending sequence
public String removeKdigits(String num, int k) {
    if (num == null || num.length() == 0) return "0";
    Deque<Character> nums = new LinkedList<>();
    char[] digits = num.toCharArray();
    for (int i = 0; i < digits.length; i++) {
        while (!nums.isEmpty() && k > 0 && digits[i] < nums.peekLast()) {
            nums.pollLast();
            k--;
        }
        nums.offer(digits[i]);
    }
    
    while (k > 0) {
        nums.pollLast();
        k--;
    }
    
    while (!nums.isEmpty() && nums.peek() == '0') {
        nums.poll();
    }
    
    StringBuilder sb = new StringBuilder();
    while (!nums.isEmpty()) {
        sb.append(nums.poll());
    }
    
    return sb.length() == 0 ? "0" : sb.toString();
}
http://www.cnblogs.com/grandyang/p/5883736.htmlhttp://blog.csdn.net/qq508618087/article/details/52584133
思路:其基本思想是利用栈尽量维持一个递增的序列,也就是说将字符串中字符依次入栈,如果当前字符串比栈顶元素小,并且还可以继续删除元素,那么就将栈顶元素删掉,这样可以保证将当前元素加进去一定可以得到一个较小的序列.也可以算是一个贪心思想.最后我们只取前len-k个元素构成一个序列即可,如果这样得到的是一个空串那就手动返回0.还有一个需要注意的是字符串首字符不为0
使得栈中的数字尽可能保持递增顺序。
首先分析一下什么样的数是最小的数。数总是有0~9的数字组成,高位的数字越小,这个数就越小。
所以,在对一个数做删除数字处理的时候,首先要从高位上把大的数字干掉,尽可能保留小的。
举个例子 num = "143219", k = 4
这个数字可以按照递增和递减分成三段 “1”, “4321”, “9”。递减子段上除了最后一个数字,其他的都可以被删除。
如果递减子段都处理完了,还没有删满k个,那就从最右边删(因为剩下的都是递增区间段了。)
所以,在对一个数做删除数字处理的时候,首先要从高位上把大的数字干掉,尽可能保留小的。
举个例子 num = "143219", k = 4
这个数字可以按照递增和递减分成三段 “1”, “4321”, “9”。递减子段上除了最后一个数字,其他的都可以被删除。
如果递减子段都处理完了,还没有删满k个,那就从最右边删(因为剩下的都是递增区间段了。)
1:    string removeKdigits(string num, int k) {  
2:      string res = "";  
3:        
4:      for(int i =0; i<num.size(); i++) {  
5:        while(res.size()>0 && res.back() > num[i]&& k>0) {  
6:          res.pop_back();  
7:          k--;  
8:        }  
9:        res.push_back(num[i]);  
10:      }  
11:        
12:      // if k != 0, remove the digit from right  
13:      res.erase(res.size() - k, k);  
14:        
15:      // trim the zero  
16:      int i =0;  
17:      while(res[i] == '0' && i<res.size()-1) i++;  
18:        
19:      res.erase(0, i);  
20:        
21:      return res.size() == 0? "0": res;  
22:    }  
https://segmentfault.com/a/1190000017514605    public String removeKdigits(String num, int k) {
        Deque<Character> stack = new ArrayDeque<>();
        int n = num.length();
        if (k >= n) return "0";
        for (int i = 0; i < n; i++) {
            while (k > 0 && !stack.isEmpty() && stack.peek() > num.charAt(i)) {
                stack.pop();
                k--;
            }
            stack.push(num.charAt(i));
        }
        while (k > 0) {
            stack.pop();
            k--;
        }
        StringBuilder sb = new StringBuilder();
        while (!stack.isEmpty()) sb.append(stack.pop());
        sb.reverse();
        while (sb.length() > 1 && sb.charAt(0) == '0') sb.deleteCharAt(0);//bad
        return sb.toString();
    }
Use StringBuilder as stack
    public static String removeKdigits(String num, int k) {
        StringBuilder sb = new StringBuilder();
        for(char c : num.toCharArray()) {
            while(k > 0 && sb.length() != 0 && sb.charAt(sb.length() - 1) > c) {
                sb.setLength(sb.length() - 1);
                k--;
            }
            if(sb.length() != 0 || c != '0') sb.append(c);  // Only append when it is not leading zero
        }
        if(k >= sb.length()) return "0";
        sb.setLength(sb.length() - k);  // use all remaining k
        return sb.toString();  
    }
setLength(len -1) O(1)public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength); ensureCapacityInternal(newLength); if (count < newLength) { Arrays.fill(value, count, newLength, '\0'); } count = newLength;}Use array as stack
https://discuss.leetcode.com/topic/59412/a-greedy-method-using-stack-o-n-time-and-o-n-space
https://discuss.leetcode.com/topic/59501/6ms-java-solution-with-detailed-comment
    public String removeKdigits(String num, int k) {
        int digits = num.length() - k;
        char[] stk = new char[num.length()];
        int top = 0;
        // k keeps track of how many characters we can remove
        // if the previous character in stk is larger than the current one
        // then removing it will get a smaller number
        // but we can only do so when k is larger than 0
        for (int i = 0; i < num.length(); ++i) {
            char c = num.charAt(i);
            while (top > 0 && stk[top-1] > c && k > 0) {
                top -= 1;
                k -= 1;
            }
            stk[top++] = c;
        }
        // find the index of first non-zero digit
        int idx = 0;
        while (idx < digits && stk[idx] == '0') idx++;
        return idx == digits? "0": new String(stk, idx, digits - idx);
    }
http://www.voidcn.com/blog/yeqiuzs/article/p-6204756.html    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;
        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"
        while(k>0){
            stack.pop();
            k--;            
        }
        
        //construct the number from the stack
        StringBuilder sb = new StringBuilder();
        while(!stack.isEmpty())
            sb.append(stack.pop());
        sb.reverse();
        
        //remove all the 0 at the head
        while(sb.length()>1 && sb.charAt(0)=='0')
            sb.deleteCharAt(0);
        return sb.toString();
    }
https://discuss.leetcode.com/topic/59646/straightforward-java-solution-using-stackpublic String removeKdigits(String num, int k) {
        Stack<Integer> stack = new Stack<Integer>();
        if (num.length() == 0 || num.length() <= k)
            return "0";
        for (int i = 0; i < num.length(); i++) {
            int cur = num.charAt(i) - '0';
            while (!stack.isEmpty() && cur < stack.peek()
                    && num.length() - i - 1 >= (num.length() - k) - stack.size()) {
                stack.pop();
            }
            if (stack.size()<num.length()-k)
                stack.push(cur);
        }
        StringBuilder res = new StringBuilder();
        while (!stack.isEmpty())
            res.insert(0, stack.pop());
        while (res.length() > 0 && res.charAt(0) == '0')
            res.deleteCharAt(0);
        if (res.length() == 0)
            return "0";
        return res.toString();
    }
http://www.cnblogs.com/grandyang/p/5883736.html这道题让我们将给定的数字去掉k位,要使得留下来的数字最小,这题跟LeetCode上之前那道Create Maximum Number有些类似,可以借鉴其中的思路,如果n是num的长度,我们要去除k个,那么需要剩下n-k个,我们开始遍历给定数字num的每一位,对于当前遍历到的数字c,进行如下while循环,如果res不为空,且k大于0,且res的最后一位大于c,那么我们应该将res的最后一位移去,且k自减1。当跳出while循环后,我们将c加入res中,最后我们将res的大小重设为n-k。根据题目中的描述,可能会出现"0200"这样不符合要求的情况,所以我们用一个while循环来去掉前面的所有0,然后返回时判断是否为空,为空则返回“0”
string removeKdigits(string num, int k) { string res = ""; int n = num.size(), keep = n - k; for (char c : num) { while (k && res.size() && res.back() > c) { res.pop_back(); --k; } res.push_back(c); } res.resize(keep); while (!res.empty() && res[0] == '0') res.erase(res.begin()); return res.empty() ? "0" : res; }http://blog.csdn.net/mebiuw/article/details/52576884
* 这是一个非常简单的问题,贪心解决法 * 即 removeKdigits(num,k) = removeKdigits(removeKdigits(num,1),k-1) * 进行最多K轮的删除,每次从头开始寻找一位删除: * 1、要么第二位是0,这样相当于至少删了两位,很值得,必须这么做 * 2、不然,找到第一个出现下降转折的位置 删除 * */ public String removeKdigits(String num, int k) { int n; while(true){ n = num.length(); if(n <= k || n == 0) return "0"; if(k-- == 0) return num; if(num.charAt(1) == '0'){ int firstNotZero = 1; while(firstNotZero < num.length() && num.charAt(firstNotZero) == '0') firstNotZero ++; num=num.substring(firstNotZero); } else{ int startIndex = 0; while(startIndex < num.length() - 1 && num.charAt(startIndex) <= num.charAt(startIndex + 1)) startIndex ++; num=num.substring(0,startIndex)+num.substring(startIndex+1); } } }
X.
http://bookshadow.com/weblog/2016/09/18/leetcode-remove-k-digits/
解法II 问题可以转化为对偶问题:从字符串num中选取size - k个字符,使得选出的数字最小化。
首先利用字典numd保存数字'0' - '9'在原始字符串num中的出现位置。
然后循环size - k次:
按照'0' - '9'的顺序从numd中选取位置合法的数字
位置合法包含2条原则:1) 候选数字之后剩余的数字要足够多,2) 候选数字要处在已选出的数字之后
    def removeKdigits(self, num, k):
        """
        :type num: str
        :type k: int
        :rtype: str
        """
        size = len(num)
        ans = '0'
        numd = collections.defaultdict(collections.deque)
        for i, n in enumerate(num):
            numd[n].append(i)
        p = 0
        for x in range(size - k):
            for y in '0123456789':
                while numd[y] and numd[y][0] < p:
                    numd[y].popleft()
                if numd[y] and numd[y][0] <= k + x:
                    p = numd[y][0]
                    ans += y
                    numd[y].popleft()
                    break
        return str(int(ans))X. https://discuss.leetcode.com/topic/59871/two-algorithms-with-detailed-explaination
The first algorithm is straight-forward. Let's think about the simplest case: how to remove 1 digit from the number so that the new number is the smallest possible? Well, one can simply scan from left to right, and remove the first "peak" digit; the peak digit is larger than its right neighbor. One can repeat this procedure k times, and obtain the first algorithm:
string removeKdigits(string num, int k) {
        while (k > 0) {
            int n = num.size();
            int i = 0;
            while (i+1<n && num[i]<=num[i+1])  i++;
            num.erase(i, 1);
            k--;
        }
        // trim leading zeros
        int s = 0;
        while (s<(int)num.size()-1 && num[s]=='0')  s++;
        num.erase(0, s);
        
        return num=="" ? "0" : num;
    }
http://www.1point3acres.com/bbs/thread-202732-1-1.html
给一个string, 找出lexical order 最小的, size==k的, subsequence, (note, not substring)
String findMin(String s, k){} e.g.
input
s=pineapple, k==3,
output: ale
ale is the lexical order smallest subsequnce of length 3.
我是暴力求解的:
1. find the first occur position of distinct char.
2. then start from that position.
3. dfs to find lenght==3, subsequence(dfs, combination way); . visit 1point3acres.com for more.
4. find the one with smallest lexical order.
我就是说了个大概.
pop的时候需要看后面还剩几个元素了
元素不够的时候就含泪不pop了,直接push进去
比如你说的例子,其实是
f->e->d->c->cb->cba
- public class Solution {
 - 鏉ユ簮涓€浜�.涓夊垎鍦拌鍧�.
 - public String removeKdigits(String num, int k) {. 1point3acres.com/bbs
 - if(num == null || num.length() == 0) return num;
 - int len = num.length();. 1point3acres.com/bbs
 - if(len == k) return "";
 - Stack<Character> stack = new Stack<Character>();
 - char []ch = num.toCharArray();
 - int i = 0, n = num.length();
 - while(i < len){
 - while(!stack.isEmpty() && stack.size() + n-i > k && stack.peek() > ch[i]){
 - stack.pop();
 - }.鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
 - stack.push(ch[i++]);
 - }. more info on 1point3acres.com
 - // handle corner case 1111 or 1234, when k = 2. 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
 - while(stack.size() > k){-google 1point3acres
 - stack.pop();
 - }
 - StringBuilder sb = new StringBuilder();
 - while(!stack.isEmpty()). Waral 鍗氬鏈夋洿澶氭枃绔�,
 - sb.insert(0, stack.pop());
 - return sb.toString();
 - }
 - public static void main(String[] args) {.鏈枃鍘熷垱鑷�1point3acres璁哄潧
 - Solution s = new Solution();
 - String str="xyzabc";
 - int k=3;
 - System.out.println(s.removeKdigits(str, k));
 - }. 鐗涗汉浜戦泦,涓€浜╀笁鍒嗗湴
 - }
 
