现在给你一个高精度的正整数N(不超过250位),去掉其中任意k个数字(k为非负整数且小于N的位数)后,将剩下的数字按原左右次序组成一个新的非负整数。请你编程对给出的N和k,找出这个新的非负整数的最小值。
以一个具体例子解释思路:
假设N = 114514,k = 3,采用滑动窗口的方式解决此问题。在窗口移动过程中,k始终表示还剩下几个数需要删除。窗口大小正常情况都比k大1,移动到末尾时有可能窗口大小等于k,设n为窗口内部最小数字的索引值。
第一步num_list = [1,1,4,5,1,4 ],窗口 = [1,1,4,5],n = 0,窗口后移一位
第二步num_list = [1,1,4,5,1,4 ],窗口 = [1,4,5,1],n = 0,窗口后移一位
第三步num_list = [1,1,4,5,1,4 ],窗口 = [4,5,1,4],n = 2,此时把索引n之前的所有数删除,因为删除了2个数,k减2变为1,窗口后移一位
第四步num_list = [1,1,1,4 ],窗口 = [4],此时窗口移动到末尾且窗口内数字个数等于k,则把窗口内所有数字全部删除,k减1变为0
第五步num_list = [1,1,1],k = 0,所以答案就是111
代码如下:
N = int(input())
k = int(input())
num_list = []
#依次提取整数N中的每一个数字,被添加到列表num_list中
#这里注意N中最后一个数字会被排放在列表最前面
while True:
number = N % 10
num_list.append(number)
N //= 10
if N == 0:
break
#将num_list逆序
num_list = list(reversed(num_list))
#使用滑动窗口,注意窗口的大小会随着k的大小变化,k代表还能删除几个数
index = 0 #窗口起始位置从num_list第一个元素开始,索引为0
while True:
if len(num_list[index:]) == k:
#如果这个if语句成立,说明窗口一定滑动到了num_list末尾
#并且此时窗口内数字的个数就等于k
#此时把整个窗口内的数全部从num_list删去即可
n = k+1 #n设置为k+1,方便后面del操作删除窗口内的数据
k = 0
else:
#窗口内此时含有的数的个数比k大1,找到窗口内最小的数的索引n
#应该要把该窗口索引n之前的数(不包括它本身)全部删除
#在该窗口内删除了多少个数,k就减去多少
n = num_list[index:index+k+1].index(min(num_list[index:index+k+1]))
k -= n
del num_list[index:index+n] #删除操作的实施
index += 1 #窗口向前移动一位
if k == 0:
break
#从num_list恢复成整数
sum = 0
for i in range(len(num_list)):
sum = sum * 10 + num_list[i]
print(sum)
补充说明:按照我的算法,窗口内含有的元素个数在正常情况一定是比k大1的,如果窗口内元素个数不比k大1,那么窗口内元素个数一定会等于k,且在这种情况下窗口一定移动到了末尾。但是不一定窗口移动到了末尾,窗口内元素个数就一定等于k。