leetcode(中等)移掉k位数字

移掉k位数字

思路:贪心+单调栈
保证元素的大小是非递减的即可。
从第二个元素开始和左边最近的一个元素相比,如果第二个元素更小,则弹栈顶元素,弹出之后需要继续比较栈顶元素和当前的遍历到的字符,并且弹出一次k需要减1;如果第二个元素更大,或者相等,则只需呀把元素入栈。如果最终k没有用完,这个时候的栈一定是非递减的,所以需要从后往前删元素,直到k用完了。如果在还没有遍历完字符串的时候k已经用完了,这个时候需要把剩下的字符全部入栈(因为剩下的元素都不能再被删掉了)。

	let stack = [];
    //如果字符串的位数小于等于k,都返回"0"
    if(num.length <= k) return "0";

    //去掉数组的前导0
    function deleteItem(arr){
        //如果传进来的全是0构成的字符串,则直接返回"0"
        let str = arr.join("");
        let len = str.length;
        for(let i = 0; i < len; i++){
            if(str[i] !== "0"){
                return str.substring(i);
            }
        }

        return "0";
    }

    //如果整个字符串是非递减的状态,就直接从尾向前删k个元素
    //判断字符串是否是非递减的
    function inc(num){
        for(let i = 0; i < num.length - 1; i++){
            if(num[i + 1] < num[i]){
                return false;
            }
        }
        return true;
    }

    if(inc(num)){
        //删掉字符串尾部k个元素
        return num.substring(0, num.length - k);
    }

    for(let i = 0; i < num.length; i++){
        while(k > 0 && stack[stack.length - 1] > num[i]){
            stack.pop();
            k--;
        }
        if(k <= 0){
            //当k的次数用完了,需要将后续的字符全部装进去
            stack.push(num.slice(i));
            break;
        }else{
            stack.push(num[i]);
        }
    }

    //可能到最后,k还没用完,但是stack中的元素依然是非递减的,需要从后往前删元素
    while(k > 0){
        stack.pop();
        k--;
    }

    //需要去除前导0,如果使用"" + Number(stack.join(""))这种方式,那么遇到大数,Number得到的结果就是Infinity。所以最好不用这种方式。
    //如果stack是以0开头的,才需要去掉前导0
    if(stack.join("").startsWith("0")){
        return deleteItem(stack);
    }else{
        return stack.join("")
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值