LeetCode 402 Remove K Digits (单调栈 贪心 推荐)

244 篇文章 0 订阅
129 篇文章 0 订阅

Given string num representing a non-negative integer num, and an integer k, return the smallest possible integer after removing k digits from num.

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.

Constraints:

  • 1 <= k <= num.length <= 105
  • num consists of only digits.
  • num does not have any leading zeros except for the zero itself.

题目链接:https://leetcode.com/problems/remove-k-digits/

题目大意:删除k个字符使剩下的数字最小

题目分析:首先想到如果某个0的前面非0数字个数小于k,则这些数字必应被删除,因为可以减少数字位数,把这部分处理掉之后对剩余部分通过单调栈维护一个递增序列,如果存在递减的部分,将较大数字删除必能使答案更小,以下代码

4ms,时间击败96.84%

class Solution {

    public String removeKdigits(String num, int k) {
        char[] nums = num.toCharArray();
        int n = nums.length;
        if (n == k) {
            return "0";
        }
        int[] zPos = new int[n];
        int[] zCnt = new int[n];
        int cnt = 0, m = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] == '0') {
                while (i + 1 < n && nums[i + 1] == '0') {
                    i++;
                }
                zPos[m] = i;
                zCnt[m++] = cnt;
                cnt = 0;
            } else {
                cnt++;
            }
        }
        int pos = 0;
        for (int i = 0; i < m && zCnt[i] <= k; i++) {
            pos = zPos[i] + 1;
            k -= zCnt[i];
        }
        if (pos >= n) {
            return "0";
        }
        StringBuffer sb = new StringBuffer("");
        char[] stk = new char[n + 1];
        int top = 0;
        stk[++top] = nums[pos++];
        while (k > 0 && pos < n) {
            if (nums[pos] < stk[top]) {
                while (k > 0 && top > 0 && nums[pos] < stk[top]) {
                    k--;
                    top--;
                }
            }
            stk[++top] = nums[pos++];
        }
        if (pos == n) {
            top -= k;
        }
        for (int i = 1; i <= top; i++) {
            sb.append(stk[i]);
        }
        for (int i = pos; i < n; i++) {
            sb.append(nums[i]);
        }
        if (sb.length() == 0) {
            return "0";
        }
        return sb.toString();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值