跳转至

402. 移掉 K 位数字

题目描述

给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。

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

 

提示:

  • 1 <= k <= num.length <= 105
  • num 仅由若干位数字(0 - 9)组成
  • 除了 0 本身之外,num 不含任何前导零

解法

方法一:贪心算法

前置知识:两个相同位数的数字大小关系取决于第一个不同位的数的大小。

基本的思路如下:

  • 从左到右遍历数组元素;
  • 对于遍历到的当前元素,选择保留;
  • 但可以选择性丢弃前面的相邻元素,丢弃与否取决于当前元素和前面相邻元素的大小;
  • 根据前置知识可知当当前元素小于前面相邻元素时可以移除前面相邻的元素。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
    def removeKdigits(self, num: str, k: int) -> str:
        stk = []
        remain = len(num) - k
        for c in num:
            while k and stk and stk[-1] > c:
                stk.pop()
                k -= 1
            stk.append(c)
        return ''.join(stk[:remain]).lstrip('0') or '0'
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
    public String removeKdigits(String num, int k) {
        StringBuilder stk = new StringBuilder();
        for (char c : num.toCharArray()) {
            while (k > 0 && stk.length() > 0 && stk.charAt(stk.length() - 1) > c) {
                stk.deleteCharAt(stk.length() - 1);
                --k;
            }
            stk.append(c);
        }
        for (; k > 0; --k) {
            stk.deleteCharAt(stk.length() - 1);
        }
        int i = 0;
        for (; i < stk.length() && stk.charAt(i) == '0'; ++i) {
        }
        String ans = stk.substring(i);
        return "".equals(ans) ? "0" : ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public:
    string removeKdigits(string num, int k) {
        string stk;
        for (char& c : num) {
            while (k && stk.size() && stk.back() > c) {
                stk.pop_back();
                --k;
            }
            stk += c;
        }
        while (k--) {
            stk.pop_back();
        }
        int i = 0;
        for (; i < stk.size() && stk[i] == '0'; ++i) {
        }
        string ans = stk.substr(i);
        return ans == "" ? "0" : ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
func removeKdigits(num string, k int) string {
    stk, remain := make([]byte, 0), len(num)-k
    for i := 0; i < len(num); i++ {
        n := len(stk)
        for k > 0 && n > 0 && stk[n-1] > num[i] {
            stk = stk[:n-1]
            n, k = n-1, k-1
        }
        stk = append(stk, num[i])
    }

    for i := 0; i < len(stk) && i < remain; i++ {
        if stk[i] != '0' {
            return string(stk[i:remain])
        }
    }
    return "0"
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function removeKdigits(num: string, k: number): string {
    const stk: string[] = [];
    for (const c of num) {
        while (k && stk.length > 0 && stk[stk.length - 1] > c) {
            stk.pop();
            k--;
        }
        stk.push(c);
    }
    while (k--) {
        stk.pop();
    }
    return stk.join('').replace(/^0*/g, '') || '0';
}

评论