通过率 54% · 提交 1,195 · 通过 650
给一个正整数 NUM1,计算出新正整数 NUM2。NUM2 为 NUM1 中移除 N 位数字后的结果,需要使得 NUM2 的值最小。
这类题属于华为 OD 机考真题方向中「100分 / 2024E」方向的高频题型,通常考察对「100分 / 2024E」的建模能力与边界条件处理。掌握本题的解题思路后,可举一反三应对同类真题方向,稳步提升机考通过率。
输入的第一行为一个字符串,字符串由 0-9 字符组成,记录正整数 NUM1,NUM1 长度小于 32。
输入的第二行为需要移除的数字的个数,小于 NUM1 长度。
输出一个数字字符串,记录最小值 NUM2。
示例 1
输入示例
2615371 4
输出示例
131
移除 2、6、5、7 这四个数字,剩下 1、3、1 按原有顺序排列组成 131 为最小值。
示例 2
输入示例
12345 2
输出示例
123
示例 3
输入示例
10345 2
输出示例
时间限制 1000 ms · 内存限制 128 MB
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。
相关图解步骤
先看指定步骤补关键知识点,再回到本题完成标准输入输出。
注意,本题和 移掉K位数字 完全一致。
对于两个相同长度的数字序列,最左边不同的数字决定了这两个数字的大小。 例如,对于两个五位数,A = 1axxx,B = 1bxxx,如果 a > b 则存在 A > B。
贪心地思考这个问题,为了使得剩下的数字尽可能地小,我们肯定希望位于前面的大的数字被尽量删掉。 换句话说,若要使得剩下的数字最小,需要保证靠前的数字尽可能小。
假设我们从左到右正序遍历原数字(字符串形式)中的每一个数字字符 ch,如果当前字符比之前遍历过遇到的字符更小,则之前遇到过的字符应该被当前这个更小的字符顶替。 这些之前遇到过的更大字符,显然可以用单调栈来储存。即如下代码:
同时,由于题目规定了最多删除的次数 n,因此我们还需要控制删除的次数。 可以需要构建一个变量 rest_n,来表示还剩下多少次可以进行的删除操作。
因此,出栈条件除了常规的 len(stack) 和 ch < stack[-1],还要再加上一条 rest_n > 0。 同时,一旦进入出栈的 while 循环,就得进行 rest_n 的递减,表示消耗了一次删除的机会。
故整个单调栈算法的核心代码为:
注意到,删除了 n 次后的数字长度一定为 len(NUM1) - n,但是单调栈中最终的元素长度并不一定是 len(NUM1) - n,即 n 次删除机会没有用完,rest_n 在退出 for 循环之后没有降为 0(譬如示例二)。 故最终单调栈中的有效数字仅为前 len(NUM1) - n 个元素,最终取 stack[:len(NUM1) - n] 作为答案。
复杂度分析 设数字字符串 NUM1 的长度为 m,允许删除的位数为 n。
瓶颈就在这一趟带弹栈的遍历上,没有排序或额外的嵌套扫描;rest_n 的控制只增加常数开销。
登录后可查看你在本题的历史提交,以及每次的各用例通过情况。
034
© 2026 广州慕课网络科技有限公司 · 吴师兄学算法官网 版权所有