移掉k个数字

题目来源:力扣(LeetCode)

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

给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

注意:

  • num 的长度小于 10002 且 ≥ k。

  • num 不会包含任何前导零。

示例 1 :

输入: num = “1432219”, k = 3

输出: “1219”

解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。

示例 2 :

输入: num = “1432219”, k = 3

输出: “1219”

解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。

示例 3 :

输入: num = “10”, k = 2

输出: “0”

解释: 从原数字移除所有的数字,剩余为空就是0。

思路

使用贪心算法,让较小的数在高位,优先从最高为开始考虑

数据结构:单调栈,压栈规则,如果比当前元素小,就向外弹;如果比当前元素大,就直接压

代码实现

import java.util.Scanner;
import java.util.Stack;

public class RemoveKdigits {
    public String removeKdigits(String num, int k) {
        Stack<Integer> stack = new Stack<>();
        //如果需要移除的个数大于等于数的长度
        if (k >= num.length()) {
            return "0";
        }
        //数的长度
        int n = num.length();
        //记录跳出的下标
        int breakIndex = -1;
        for (int i = 0; i < n; i++) {
            //如果移除的个数等于k,就跳出,不在移除
            if (k == 0) {
                breakIndex = i;
                break;
            }
            int temp = num.charAt(i) - '0';
            //如果栈非空并且栈顶元素大于当前元素,出栈
            while (!stack.isEmpty() && stack.peek() > temp && k > 0) {
                k--;
                stack.pop();
            }
            //如果栈为空并且为0是不能添加的
            if (!stack.isEmpty() || temp != 0) {
                stack.push(temp);
            }
        }
        //如果还没有移除完,继续出栈
        while (k > 0) {
            stack.pop();
            k--;
        }

        StringBuilder str = new StringBuilder();
        while (!stack.isEmpty()) {
            //从头部添加
            str.insert(0, stack.pop());
        }
        //如果是中途跳出循环
        if (breakIndex != -1) {
            str.append(num.substring(breakIndex));
        }
        //这是因为 (10 , 1)这样的类似案例
        return str.length() == 0 ? "0" : str.toString();
    }
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务