题目描述与示例
题目描述
给一个正整数 NUM1
,计算出新正整数 NUM2
。NUM2
为 NUM1
中移除 N
位数字后的结果,需要使得 NUM2
的值最小。
输入
- 输入的第一行为一个字符串,字符串由
0-9
字符组成,记录正整数NUM1
,NUM1
长度小于32
。 - 输入的第二行为需要移除的数字的个数,小于
NUM
1 长度。
输出
输出一个数字字符串,记录最小值 NUM2
。
示例一
输入
2615371
4
输出
131
说明
移除 2
、6
、5
、7
这四个数字,剩下 1
、3
、1
按原有顺序排列组成 131
为最小值。
示例二
输入
12345
2
输出
123
示例三
输入
10345
2
输出
034
解题思路
注意,本题和LC402. 移掉K位数字完全一致。
代码
Python
# 题目:2023B-找最小数
# 分值:200
# 作者:闭着眼睛学数理化
# 算法:单调栈
# 代码看不懂的地方,请直接在群上提问
NUM1 = input()
n = int(input())
# rest_n 表示剩余的删除次数
rest_n = n
# 构建一个单调栈,
# 单调栈从栈底至栈顶单调递增
# 即大的数字放在栈顶
stack = list()
# 遍历数字字符串NUM1中的每一个字符ch
for ch in NUM1:
# 出栈的情况:
# 1. 栈不为空
# 2. ch小于栈顶元素
# 3. 剩余的删除次数大于0
# 即可以弹出栈顶元素,这样才能使得栈顶元素尽可能小
while len(stack) and ch < stack[-1] and rest_n > 0:
stack.pop()
rest_n -= 1
# 对于每一个ch,都应该入栈
stack.append(ch)
# 结束循环时,栈中元素不一定恰好为len(NUM1)-n
# 所以取较小的数前 len(NUM1)-n 个数组合成字符串
print("".join(stack[:len(NUM1)-n]))
Java
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String NUM1 = scanner.nextLine();
int n = scanner.nextInt();
int rest_n = n;
Stack<Character> stack = new Stack<>();
for (char ch : NUM1.toCharArray()) {
while (!stack.isEmpty() && ch < stack.peek() && rest_n > 0) {
stack.pop();
rest_n--;
}
stack.push(ch);
}
StringBuilder result = new StringBuilder();
int len = NUM1.length() - n;
for (int i = 0; i < len; i++) {
result.append(stack.get(i));
}
System.out.println(result.toString());
}
}
C++
“`C++
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int main() {
string NUM1;
int n;
cin >> NUM1 >> n;
<pre><code>int rest_n = n;
stack<char> stack;
for (char ch : NUM1) {
while (!stack.empty() && ch < stack.top() && rest_n > 0) {
stack.pop();
rest_n–;
}
stack.push(ch);
}
string result;
int len = NUM1.size() – n;
while (!stack.empty()) {
result = stack.top() + result;
stack.pop();
}
result = result.substr(0, len);
cout << result << endl;
return 0;
</code></pre>
}
“`
时空复杂度
时间复杂度:O(M)
。仅需一次遍历字符串NUM1
。
空间复杂度:O(M)
。单调栈所占用的额外空间。
M
为字符串NUM1
的长度。
说明
华为OD机试有三道题⽬,第⼀道和第⼆道属于简单或中等题,分值为 100 分,第三道为中等或困难题,分值为 200分,总分为 400 分。
机试分数越⾼评级越⾼,⼯资也就越⾼。
关于华为 OD 机试更加详细的介绍可以查看这篇⽂章:华为OD机考须知
关于机考题目汇总可以看这篇文章:华为OD机试真题 2023 A+B+C+D卷 + 2024新卷(Python&Java&C++)⽬录汇总(每⽇更新)