• letcode每日一题-移掉K位数字


    项目描述如下:

    思路:
    我自己想的是使用贪心算法
    对于两个相同长度的数字序列,最左边不同的数字决定了这两个数字的大小,例如,对于 A = 1axxxA=1axxx,B = 1bxxxB=1bxxx,
    如果 a > ba>b 则 A > BA>B。
    基于此,我们可以知道,若要使得剩下的数字最小,需要保证靠前的数字尽可能小。

    基于此我的代码实现如下:

    
    public String removeKdigits(String num, int k) {
            LinkedList<Character> tmp=new LinkedList<>();
            int i=0;
            //构建临时结果列表
            for(;i<num.length()-k;i++){
                tmp.add(num.charAt(i));
            }
            for(;i<num.length();i++){
                tmp.add(num.charAt(i));
                //删除一个数字
                removeBig(tmp);
            }
            StringBuilder result=new StringBuilder();
            for(Character charTmp:tmp){
                if(charTmp=='0' && result.length()==0){
                    continue;
                }
                result.append(charTmp);
            }
            return result.length()==0?"0":result.toString();
        }
    
        public void removeBig(LinkedList<Character> tmp){
            char prev=' ';
            int index=-1;
            for(Character charTmp:tmp){
                if(prev!=' '&& prev>charTmp){
                    break;
                }
                prev=charTmp;
                index++;
            }
            tmp.remove(index);
        }
    
    

    然而暴力的实现复杂度最差会达到 O(nk)(考虑整个数字序列是单调不降的),因此我们需要加速这个过程。
    考虑从左往右增量的构造最后的答案。我们可以用一个栈维护当前的答案序列,栈中的元素代表截止到当前位置,
    删除不超过 k 次个数字后,所能得到的最小整数。根据之前的讨论:在使用 k 个删除次数之前,栈中的序列从
    栈底到栈顶单调不降。
    因此,对于每个数字,如果该数字小于栈顶元素,我们就不断地弹出栈顶元素,直到
    栈为空
    或者新的栈顶元素不大于当前数字
    或者我们已经删除了 k位数字
    上述步骤结束后我们还需要针对一些情况做额外的处理:

    如果我们删除了 mm 个数字且 m<km<k,这种情况下我们需要从序列尾部删除额外的 k-mk−m 个数字。
    如果最终的数字序列存在前导零,我们要删去前导零。
    如果最终数字序列为空,我们应该返回 00。
    最终,从栈底到栈顶的答案序列即为最小数。

    考虑到栈的特点是后进先出,如果通过栈实现,则需要将栈内元素依次弹出然后进行翻转才能得到最小数。为了避
    免翻转操作,可以使用双端队列代替栈的实现。

    代码实现如下:

    
    public String removeKdigits(String num, int k) {
            Deque<Character> queue=new LinkedList<>();
            //我们假设num是一个递减的队列
            for(int i=0;i<num.length();i++){
                char tmpChar=num.charAt(i);
                while (!queue.isEmpty() && k>0 && tmpChar<queue.peekLast()){
                    queue.pollLast();
                    k--;
                }
                queue.offerLast(tmpChar);
            }
            //处理单调递增的队列
            for (int i=0;i<k;i++){
                queue.pollLast();
            }
            StringBuilder result=new StringBuilder();
            while (!queue.isEmpty()){
                char charTmp=queue.pollFirst();
                if(charTmp=='0' && result.length()==0){
                    continue;
                }
                result.append(charTmp);
            }
            return result.length()==0?"0":result.toString();
        }
    
    
  • 相关阅读:
    jenkins本地运行方法
    项目开发规则
    finally与catch的执行
    idea中实现热部署
    vue的错误的ERR!代码ELIFECYCLE
    spring注解的使用
    mysql中with as相关用法8.0之后支持
    stream流遇到的问题
    git解决冲突,在乌龟工具中一定要点击提交
    jquery知识 内部 外部插入元素
  • 原文地址:https://www.cnblogs.com/MissWX/p/14074657.html
Copyright © 2020-2023  润新知