1. 程式人生 > >402. Remove K Digits - Medium

402. Remove K Digits - Medium

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.

 

思路:

首先考慮只刪除一個數的情況。刪除一個數字,結果都是總位數減少一位,在剩下相同位數的整數裡,優先把高位的數字降低,對新整數的值影響最大。

遍歷原整數,從左到右進行比較,如果某一位的數字大於它右邊的數字,說明刪除該數字後會使該數位的值降低。

每一步都找出刪除一個數後的最小值,重複k次,結果就是刪除k個數的最小值。(區域性最優->全域性最優)

 

注意: 用k作為外迴圈,遍歷數字作為內迴圈的話時間複雜度太高。應把k作為內迴圈.

detail:遍歷原整數的時候,用一個stack,讓每數字入棧,當某個數字需要被刪除時讓它出棧即可。最後返回由棧中數字構成的新整數

因為可能棧的第一個元素為0,最後要再遍歷一下棧中的元素,找到第一個非0的index。手動寫一個由陣列構成的stack更方便。

時間:O(N),空間:O(N)

class Solution {
    public String removeKdigits(String num, int k) {
        int len = num.length() - k;
        
        char[] stack = new char[num.length()];
        int top = 0;
        for(int i = 0; i < num.length(); i++) {
            char c = num.charAt(i);
            while(k > 0 && top > 0 && stack[top-1] > c) {
                top -= 1;
                k -= 1;
            }
            stack[top++] = c;
        }
        int idx = 0;
        while(idx < len && stack[idx] == '0')
            idx++;
        
        return idx == len ? "0" : new String(stack, idx, len - idx);
    }
}