【LeetCode】402、移除K位数字

1、移除K位数字

题目:402. 移掉K位数字

题目描述:

??给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。(num 的长度小于 10002 且 ≥ k。

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

示例 :

    输入: num = "1432219", k = 3
    输出: "1219"
    解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219。

    输入: num = "10200", k = 1
    输出: "200"
    解释: 移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。

    输入: num = "10", k = 2
    输出: "0"
    解释: 从原数字移除所有的数字,剩余为空就是0。


解题思路:基于单调栈的贪心算法

??对于两个长度相同的数字,其最左边的数字决定了这两个数字的大小,左边的数字越小,数字也越小,比如如果由相同的元素组成的数字,升序序列是最小的。所以我们的想法是尽可能地使左边的数字小

??所以,给定一个数字序列[a,b,c,d,e,f],如果数字b小于其左邻居 a,则我们应该删除左邻居a,以获得最小结果。

??对于每个数字,如果该数字小于栈顶部,即该数字的左邻居,则弹出堆栈,即删除左邻居。否则,我们把数字推到栈上。

重复上述步骤,直到任何条件不再适用,例如堆栈为空(不再保留数字)。或者已经删除了 k 位数字。

??同时,这里需要注意一些特殊情况:

??1、如果整个序列是单增的,我们会发现左邻居永远小,所以应该删除掉末尾的k个数字即可。

??2、在完成整个循环后,栈中弹出的数字是逆序的,需要反转,需要注意的是结果可能出现前导零,需要考虑到这种情况,将前导零删除。

代码实现:

class Solution {
    public String removeKdigits(String num, int k) {
        //基于单调栈的贪心思想
        if(k==0)
            return num;
        if(num.length()==0 || k>=num.length())
            return "0";

        Stack<Character> stack=new Stack<>();  //维护一个单调栈

        for(int i=0;i<num.length();i++){
            char c=num.charAt(i);
            while(!stack.isEmpty() && stack.peek()>c && k>0 ){
                stack.pop();  //左边的大则删除,本质是贪心
                k--;
            }
            stack.push(c);
        }

        //特别注意:如果没有删够k次,说明剩下的是单调不减的,则从末尾删除即可
        for(int i=0;i<k;i++)  //剩余多少次由k决定
            stack.pop();

        //最后将栈中的元素弹出并反转即可
        StringBuffer str=new StringBuffer();
        while(!stack.isEmpty()){
            str.append(stack.pop());
        }

        str=str.reverse(); //反转

        //去除前导0
        int index=0;
        while(index<str.length() && str.charAt(index)==‘0‘)
            index++;

        String res=str.toString().substring(index);

        return res.length()==0?"0":res;
    }
}

2、字典序最大的子序列

题目描述:

??给定?个字符串,得到它字典序最?的?序列。(换言之,也就是删除?些字符,使得剩下的字符构成的字符串字典序是最?的)

解题思路:

??两个字符串相比,字典序的大小首先是对排在前列的字符进行比较,越靠前的字符越大,整体的字典序就越大,因此,要想字典序最大,应该将其变为一个单调递减的子序列

??因此,这和上一题实际上类似的,只是没有了删除k次的限制,同样应该利用一个单调栈,当栈顶数字小于当前考察的元素时,即将其栈顶数字删除,最后在栈中形成一个单调递减(严格来说是单调不增)的子序列。

代码实现

??与上题代码基本类似,核心在于基于单调栈的贪心思想,越靠前的越大越好。

原文地址:https://www.cnblogs.com/gzshan/p/12560566.html

时间: 2024-08-27 20:52:51

【LeetCode】402、移除K位数字的相关文章

Leetcode 402. 移掉K位数字

// 贪心算法,当前遇到的数,比栈顶的元素小,就将栈顶元素给弹出,直至遇到比栈顶大或者是栈为空才停止,字符串保证是一个正常的数字序列.class Solution { public: string removeKdigits(string num, int k) { std::vector<int> S;//为了遍历,因此可以用vector来进行模拟. std::string result = "";// 保存最后的结果 for(int i=0; i<num.size

算法46----移除K位数字

一.题目:移除K位数字 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 示例 1 : 输入: num = "1432219", k = 3 输出: "1219" 解释: 移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219. 示例 2 : 输入: num = "10200", k = 1 输出: "

贪心算法-移除K个数字

1.题目描述 给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k. num 不会包含任何前导零. 2.题目分析: 题目简介明了,就是把给定的数字删除指定个数的数字使删除之后的数字是同等位数数字中最小的那个.但是需要注意的是,题目中给的数字是字符串的形式并且输出结果也是字符串的形式,这就涉及到字符串和数字之间的相互转化问题. 题目中要求删除的数字个数是不确定的,那么我们可以根据数学知识先分析当我们删除一个数字

[LeetCode] Remove K Digits 去掉K位数字

Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible. Note: The length of num is less than 10002 and will be ≥ k. The given num does not contain any leading zero. Ex

(笔试题)删除K位数字

题目: 现有一个 n 位数,你需要删除其中的 k 位,请问如何删除才能使得剩下的数最大? 比如当数为 2319274, k=1 时,删去 2 变成 319274 后是可能的最大值. 思路: 1.贪心算法 每次从高位向低位数,删除高位数字比低位数字小的那位数字.如2319274 第一次2<3,删除2,得到319274 第二次3>1,略过,1<9,删除1,得到39274 第三次3<9,删除3,得到9274 ...... // greedy method string deleteKBi

[小米OJ] 9. 移除 K 位得到最小值

思路: 重复k次: 1.找到并且删除第一个 num[i] > num[i+1] 的第i位数字. 2.若删除过程中,序列变成递增序列,则直接删除最后一位. 注意除去字符串头的0 def solution(line): num, k = line.split(" ") for j in range(0, int(k)): flag = True for i in range(0, len(num)-1): if num[i] > num[i+1]: flag = False n

rqnoj 相同的后k位

题目描述 路人甲给你出了一道奇怪的问题,他给你了一个正整数L,他想知道当正整数m,n为何值时,L^m与L^n的最后K位数字相同. 路人甲考虑到可能会有很多组解,你只需要告诉他最小的m,n且0<n<m. 输入格式 一个正整数L,一个正整数k 输出格式 输出一个最小的m,n 样例输入 样例输出 注释 [数据规模及约定] 100<=L<=9999 1<=k<=4 #include<iostream> #include<cstdio> #include&

leetcode [402]Remove K Digits

Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible. Note: The length of num is less than 10002 and will be ≥ k. The given num does not contain any leading zero. Ex

把一个数组向右循环移动k位要求时间复杂度为O(n)

今晚做了下某公司的网络笔试题,好久没刷题了,现在渣得要死,里面有道程序设计题是 把一个数组向右循环移动k位要求时间复杂度为O(n) 给的方法定义为 public void solution(int a[],int length,int k) 我当时觉得挺容易的,结果一写出来发现只能移一位... public void solution(int []a,int length,int k){ int temp=a[length-1]; for(int j=length-1;j>0;j--){ a[j