3948.字典序最大的MEX数组
难度:困难
问题描述:
给你一个整数数组nums。
你需要构造一个数组result,具体做法是重复执行以下操作,直到nums变为空:
选择一个整数k,满足1<=k<=len(nums)。
计算nums的前k个元素的MEX。
将这个MEX附加到result。
从nums中移除前k个元素。
返回执行这些操作后能得到的字典序最大的数组result。
数组的MEX是指数组中不包含的最小非负整数。
如果两个数组a和b在第一个不同的下标处,数组a的元素大于数组b的对应元素,则数组a字典序大于数组b。如果前min(a.length,b.length)个元素都相同,那么较长的数组是字典序更大的数组。
示例1:
输入:nums=0,1,0
输出:2,1
解释:
取前k=2个元素0,1,其MEX=2。当前result=2。
剩余数组0的MEX=1。因此,最终的result=2,1。
示例2:
输入:nums=1,0,2
输出:3
解释:
取前k=3个元素1,0,2,其MEX=3。
nums现在为空。因此,最终的result=3。
示例3:
输入:nums=3,1
输出:0,0
解释:
取k=1,第一个元素3的MEX=0。当前result=0。
剩余数组1的MEX=0。因此,最终的result=0,0。
提示:
1<=nums.length<=10**5
0<=numsi<=10**5
问题分析:
解决本问题,要处理两个问题,一是MEX要大,二是在MEX尽可能大的同时,处理次数尽可能多,这样才能得到字典序最大的result数组。为此设计两个函数,一是 get_mex(a),其功能是找出一个数组a中不包含的最小非负整数MEX,二是split_array(a),其功能是对一个数组a进行最小拆分,返回拆分位置和MEX值。主程序利用循环,将每一次得到的MEX添加到result中,并根据拆分位置,生成下一次要进行拆分处理的数组a,直到不能拆分为止,最后输出result即可。
程序如下:
python
#找出一个数组中不包含的最小非负整数即MEX并返回
def get_mex(a):
b=list(x for x in a if x>=0)
c=sorted(list(set(b)))
i=0
while True:
if i in c:
i+=1
continue
else:
return i
#将a分成两部分,从第一个元素开始向后面查找,直到某一个元素之后,若前面部分(包括这个元素)的mex=mex,返回索引号i和mex
# 如果这个元素是最后一个元素,则返回n和mex
def split_array(a):
m=get_mex(a)
n=len(a)
for i in range(1,n+1):
t=a[:i]
if get_mex(t)==m:
return [i,m]
else:
continue
#主程序
a=eval(input('pls input a='))
result=[]
n=len(a)
while True:
i, m = split_array(a)
if i==n:
result.append(m)
break
else:
result.append(m)
a=a[i:]
n=len(a)
print(result)
运行实例一
pls input a=3,2,1,0,1,2,1
4, 0, 0, 0
运行实例二
pls input a=-1,2,1,0,-3,0,1
3, 2