04137: 最小新整数
stack, greedy, http://cs101.openjudge.cn/practice/04137/
给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。 现在从m位中删除k位(0<k < m),求生成的新整数最小为多少? 例如: n = 9128456, k = 2, 则生成的新整数最小为12456
输入
第一行t, 表示有t组数据; 接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出
t行,每行一个数字,表示从n中删除k位后得到的最小整数。
样例输入
2
9128456 2
1444 3样例输出
12456
1python
# 蒋子轩23工学院
def removeKDigits(num, k):
stack = []
for digit in num:
while k and stack and stack[-1] > digit:
stack.pop()
k -= 1
stack.append(digit)
# 如果还未删除k位,从尾部继续删除
while k:
stack.pop()
k -= 1
return int(''.join(stack))
t = int(input())
results = []
for _ in range(t):
n, k = input().split()
results.append(removeKDigits(n, int(k)))
for result in results:
print(result)单调栈是一种特殊的栈结构,其中的元素按照某种特定的顺序(如递增或递减)排列。在计算机科学中,单调栈常用于解决一类与数组或序列相关的优化问题,比如寻找下一个更大或更小的元素等。
单调栈的应用场景
- 寻找下一个更大的元素:给定一个数组,对于每个元素,找到它右边第一个比它大的元素的位置。这类问题可以使用单调递减栈来高效解决。
- 寻找下一个更小的元素:类似地,如果需要找到每个元素右边第一个比它小的元素的位置,则可以使用单调递增栈。
- 直方图中的最大矩形:这是一个经典的问题,涉及到计算直方图中最大的矩形面积,可以使用单调栈来有效求解。
- 滑动窗口的最大值:虽然这个问题通常使用双端队列来解决,但也可以通过单调栈的变形来处理。
单调栈的工作原理
- 入栈操作:当一个新的元素需要加入到栈中时,根据栈的性质(递增或递减),将所有不符合条件的栈顶元素弹出,然后再将新元素压入栈中。
- 出栈操作:通常情况下,出栈操作是自动发生的,即在执行入栈操作时,为了保持栈的单调性,会自动移除不满足条件的栈顶元素。
实现示例
这里以一个简单的例子说明如何使用单调栈来解决问题。假设我们需要找到数组 [4, 5, 2, 25] 中每个元素右边第一个更大的数。
python
def next_greater_element(nums):
stack = []
result = [0] * len(nums)
for i in range(len(nums)):
# 当栈不为空且当前考察的元素大于栈顶元素时
while stack and nums[i] > nums[stack[-1]]:
index = stack.pop()
result[index] = nums[i]
# 将当前元素的索引压入栈中
stack.append(i)
# 对于栈中剩余的元素,它们没有更大的元素
while stack:
index = stack.pop()
result[index] = -1
return result
nums = [4, 5, 2, 25]
print(next_greater_element(nums)) # 输出: [5, 25, 25, -1]在这个例子中,我们维护了一个单调递减的栈,当遇到比栈顶元素大的数时,就找到了栈顶元素的“下一个更大的数”,然后将其从栈中弹出,并记录结果。最后,对于那些在栈中没有匹配到更大数的元素,它们的结果设置为 -1,表示没有更大的数。