网易首页 > 网易号 > 正文 申请入驻

2026-09-08:字典序最大的 MEX 数组。用go语言,给定一个整数数组,我们需要通过重复操作将其全部截取完毕,并在每一步构造出一个新数组

0
分享至

2026-09-08:字典序最大的 MEX 数组。用go语言,给定一个整数数组,我们需要通过重复操作将其全部截取完毕,并在每一步构造出一个新数组。每一步的操作规则是:先选定一个正整数 k,其值不能超过当前数组剩余的长度;然后取出当前数组开头的 k 个元素,计算出这 k 个数中的 MEX(即缺失的最小非负整数);把这个 MEX 数值依次追加到结果数组中;接着从原数组中删掉刚刚取出的这 k 个元素。整个过程持续到原数组为空为止。我们的最终目标,是通过每一步合理选择 k 的取值,使得最后得到的结果数组在字典序上尽可能大。字典序的比较方式是从前往后逐个对比元素,第一次出现不同时,数值较大的数组更优;如果较短数组的所有元素都能与较长数组的对应位置完全一致,那么长度更长的数组视为更大。

1 <= nums.length <= 100000。

0 <= nums[i] <= 100000。

输入: nums = [0,1,0]。

输出: [2,1]。

解释:

取前 k = 2 个元素 [0, 1],其 MEX = 2。当前 result = [2]。

剩余数组 [0] 的 MEX = 1。因此,最终的 result = [2, 1]。

题目来自力扣3948。

一、预处理阶段

  1. 1. 设原数组长度为n。因为 MEX 最大不可能超过n(即使数组包含0..n-1所有数,MEX 也仅为n),所以所有大于等于n的数对于 MEX 的计算没有任何影响,直接忽略。

  2. 2. 创建一个pos结构,pos[x]是一个列表,用来存储原数组中所有值等于x的下标(仅存储x < n的情况)。

  • • 遍历原数组,如果nums[i] < n,就把下标i加入pos[nums[i]]。

3. 为了后续方便地找到某个值在当前剩余数组中最靠左的位置,把每个pos[x]列表反转,使得列表的末尾存放的是该值在原数组中的最小下标。这样每次只需要查看列表末尾,即可得到当前剩余数组中最左边的x的位置,并且可以用pop操作快速移除已经不在剩余数组中的旧下标。

二、主循环:逐段确定最大 MEX

用变量i表示当前剩余数组的起始下标(在原数组中的位置)。初始时i = 0。

只要i < n,就说明还有元素未被截取,开始构造下一段:

  1. 1.设置当前段的起点
    start = i,表示这一段从原数组的start位置开始。

  2. 2.从mex = 0开始尝试扩展当前段的 MEX
    不断检查当前剩余数组中是否存在值mex:

    这个过程相当于:从0开始,只要能找到0、1、2…… 就不断把段向右扩展,直到遇到第一个缺失的值。最终得到的mex就是当前段能够达到的最大 MEX。

  • • 取出pos[mex]列表。

  • •清理过期下标:
    弹出列表末尾所有小于start的下标。这些下标属于已经被之前段截掉的部分,不再属于当前剩余数组。清理之后,列表末尾就是当前剩余数组中值mex的最左位置(如果存在的话)。

  • • 如果清理后列表为空,说明当前剩余数组中已经不存在值mex,因此当前段的 MEX 最大就是mex,跳出循环。

  • • 如果列表非空,说明当前剩余数组中存在值mex。为了让当前段包含这个值,段必须至少延伸到该值在当前剩余数组中最左的位置。因此,如果该位置大于当前段的右边界i,就更新i为该位置。

  • • 然后mex += 1,继续检查下一个值是否能被包含进当前段。

3.记录结果并进入下一段
将得到的mex追加到结果数组ans中。
当前段覆盖的原数组区间是[start, i](其中i是扩展后的右边界)。删除这一段后,剩余数组从i + 1开始。
所以执行i++,继续下一轮外层循环。

三、示例说明

以输入nums = [0, 1, 0]为例:

  • • 预处理:

    • •pos[0] = [0, 2],反转后为[2, 0]

    • •pos[1] = [1]

    • •pos[2] = []

  • • 第一段:

    • •start = 0,i = 0,mex = 0

    • •pos[0]末尾是0,不小于start,保留。i仍为0。mex=1

    • •pos[1]末尾是1,不小于start,保留。1 > i,更新i = 1。mex=2

    • •pos[2]为空,跳出。得到 MEX = 2。
      第一段为[0, 1],结果[2],删除后i = 2。

  • • 第二段:

    • •start = 2,i = 2,mex = 0

    • •pos[0]末尾是0,小于start=2,弹出;新末尾为2,不小于start,保留。i仍为2。mex=1

    • •pos[1]末尾是1,小于start=2,弹出,列表空,跳出。得到 MEX = 1。
      第二段为[0],结果追加1,最终[2, 1]。

四、时间复杂度分析
  • •预处理:遍历原数组一次,并将部分下标加入pos,然后反转所有列表,总耗时为O(n)。

  • •主循环:

    • • 外层i从0递增到n,最多执行n次。

    • • 内层对mex的检查中,每个下标在清理时最多被弹出一次,所有pos列表的元素总数不超过n,所以总弹出操作为O(n)。

    • • 另外,每一段中mex从0递增到该段的 MEX。由于每段的 MEX 不超过该段的长度,而所有段的长度之和为n,所以所有段的 MEX 之和也不超过n。因此内层mex递增的总次数也是O(n)。

综上,总时间复杂度为 O(n)。

五、额外空间复杂度分析

  • •pos结构存储了所有值小于n的元素下标,这些下标总数不超过n,所以存储这些下标的额外空间为O(n)。

  • •ans结果数组最多包含n个元素,也是O(n)。

  • • 其他辅助变量和切片头开销均为常数或O(n)级别。

因此,总的额外空间复杂度为 O(n)。

Go完整代码如下:

package main

import "fmt"

func maximumMEX(nums []int) []int {
n := len(nums)
// mex 最大是 n,>= n 的数无需考虑
pos := make([][]int, n+1) // n 作为哨兵
for i, x := range nums {
if x < n {
pos[x] = append(pos[x], i)
}
}
// 反转每个列表,使最小索引位于末尾,便于弹出
for _, p := range pos {
for i, j := 0, len(p)-1; i < j; i, j = i+1, j-1 {
p[i], p[j] = p[j], p[i]
}
}

ans := []int{}
i := 0
for i < n {
start := i // 这一段的起点
mex := 0
for {
q := pos[mex]
// 清理在 start 之前的下标(末尾是最小索引)
for len(q) > 0 && q[len(q)-1] < start {
q = q[:len(q)-1]
}
pos[mex] = q
if len(q) == 0 {
break
}
// 这一段包含剩余元素中的最左边的 mex
if q[len(q)-1] > i {
i = q[len(q)-1]
}
mex++
}
ans = append(ans, mex)
i++
}
return ans
}

func main() {
nums := []int{0, 1, 0}
result := maximumMEX(nums)
fmt.Println(result)
}

Python完整代码如下:

# -*-coding:utf-8-*-

def maximumMEX(nums):
n = len(nums)
# mex 最大是 n,>= n 的数无需考虑
pos = [[] for _ in range(n + 1)] # n 作为哨兵
for i, x in enumerate(nums):
if x < n:
pos[x].append(i)
# 反转每个列表,使最小索引位于末尾,便于弹出
for p in pos:
p.reverse()
ans = []
i = 0
while i < n:
start = i # 这一段的起点
mex = 0
while True:
q = pos[mex]
# 清理在 start 之前的下标(末尾是最小索引)
while q and q[-1] < start:
q.pop()
if not q:
break
# 这一段包含剩余元素中的最左边的 mex
if q[-1] > i:
i = q[-1]
mex += 1
ans.append(mex)
i += 1
return ans

# 测试
if __name__ == "__main__":
nums = [0, 1, 0]
result = maximumMEX(nums)
print(result)

C++完整代码如下:

  


using namespace std;


vector maximumMEX(vector& nums) {
int n = nums.size();
vector int >> pos(n + 1 );
for ( int i = 0 ; i < n; ++i) {
int x = nums[i];
if (x < n) {
pos[x].push_back(i);
}
}
// 反转每个列表,使最小索引位于末尾
for (auto& p : pos) {
reverse(p.begin(), p.end());
}

vector< int > ans;
int i = 0 ;
while (i < n) {
int start = i;
int mex = 0 ;
while ( true ) {
// 清理在 start 之前的下标(末尾是最小索引)
while (!pos[mex].empty() && pos[mex].back() < start) {
pos[mex].pop_back();
}
if (pos[mex].empty()) {
break ;
}
// 这一段包含剩余元素中的最左边的 mex
if (pos[mex].back() > i) {
i = pos[mex].back();
}
mex++;
}
ans.push_back(mex);
i++;
}
return ans;
}

int main() {
vector< int > nums = { 0 , 1 , 0 };
vector< int > result = maximumMEX(nums);
for ( int x : result) {
cout << x << " " ;
}
cout << endl;
return 0 ;
}

我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。 欢迎关注“福大大架构师每日一题”,发消息可获得面试资料,让AI助力您的未来发展。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
官方:快船已经裁掉了日本后卫河村勇辉

官方:快船已经裁掉了日本后卫河村勇辉

懂球帝
2026-10-13 11:43:06
13岁女孩被约到酒店喝酒,两男子先后和她发生关系,完事还把她手机抢走卖了5300

13岁女孩被约到酒店喝酒,两男子先后和她发生关系,完事还把她手机抢走卖了5300

一丝不苟的法律人
2026-10-12 11:41:38
王皓事件升级:骂王皓的那三个女孩,被行拘仅是开胃菜,更严重的后果还在后面

王皓事件升级:骂王皓的那三个女孩,被行拘仅是开胃菜,更严重的后果还在后面

法网恢恢
2026-10-11 22:07:22
因果终会来!潇洒一生的郑少秋,熬到79岁才“离开”,遗憾终无法填补

因果终会来!潇洒一生的郑少秋,熬到79岁才“离开”,遗憾终无法填补

LULU生活家
2026-10-13 08:58:25
1980年,邓小平说:毛主席的错误,要毫不含糊地批评,但要实事求是

1980年,邓小平说:毛主席的错误,要毫不含糊地批评,但要实事求是

帝哥说史
2026-10-11 16:14:43
不查不知道,一查吓一跳!电诈头子佘智江,生活奢靡程度远超想象

不查不知道,一查吓一跳!电诈头子佘智江,生活奢靡程度远超想象

月下守候
2026-10-13 16:31:02
电影《我不是药神》原型陆勇即将停药:24年吃了3.5万片药 曾一年吃掉一套房

电影《我不是药神》原型陆勇即将停药:24年吃了3.5万片药 曾一年吃掉一套房

快科技
2026-10-12 21:46:09
一台手机跑安卓、Linux和Windows,发货却推迟了

一台手机跑安卓、Linux和Windows,发货却推迟了

野生运营
2026-10-12 14:17:21
印尼人焚烧中国挖掘机,逮捕75名中国工人,天理难容

印尼人焚烧中国挖掘机,逮捕75名中国工人,天理难容

以色列飛飛
2026-10-12 09:00:12
14台尊界刹车踏板测试,江淮汽车扳回一局

14台尊界刹车踏板测试,江淮汽车扳回一局

鸣金网
2026-10-13 12:31:30
中国汽研确认检测出具尊界V800公布刹车踏板检验结果:根据企业提供样车进行测试,无法保证流传的报告是否经过篡改

中国汽研确认检测出具尊界V800公布刹车踏板检验结果:根据企业提供样车进行测试,无法保证流传的报告是否经过篡改

大风新闻
2026-10-13 13:40:04
北理工助教裴轶近况曝光!微博签名改成“宁鸣而死,不默而生”,很不服气

北理工助教裴轶近况曝光!微博签名改成“宁鸣而死,不默而生”,很不服气

小徐讲八卦
2026-10-13 10:47:27
上海姑娘看完孙燕姿演唱会,一台大疆相机忘拿了!现场数万人,怎么找?回家路上她刷了会手机,大数据精准推送

上海姑娘看完孙燕姿演唱会,一台大疆相机忘拿了!现场数万人,怎么找?回家路上她刷了会手机,大数据精准推送

上海约饭局
2026-10-13 15:04:06
原来她就是白应苍的枕边人,网传两人已离婚,携带孩子跑路国外

原来她就是白应苍的枕边人,网传两人已离婚,携带孩子跑路国外

娱乐圈见解说
2026-10-13 08:09:26
普通人最傻的消费,就是买一辆 20 万左右的新能源新车

普通人最傻的消费,就是买一辆 20 万左右的新能源新车

三农老历
2026-10-13 05:44:03
张雨绮直播,原来除了事业线胸围腿也这么棒

张雨绮直播,原来除了事业线胸围腿也这么棒

东方不败然多多
2026-10-13 19:04:55
突发!霍华德首秀,怒喷詹姆斯,示好76人……

突发!霍华德首秀,怒喷詹姆斯,示好76人……

体育新角度
2026-10-13 13:55:42
性专家说:当一个异性开口跟你要钱,要礼物,不管对方是不是想试探你的真心,你都应该明白,你已被对方列入供养者行列

性专家说:当一个异性开口跟你要钱,要礼物,不管对方是不是想试探你的真心,你都应该明白,你已被对方列入供养者行列

心理观察局
2026-08-05 06:46:04
男性若有这4个爱好,往往寿命更长,占一个也不错,你有几个?

男性若有这4个爱好,往往寿命更长,占一个也不错,你有几个?

坠入二次元的海洋
2026-10-13 07:22:50
“太窒息了,我要是孩子直接跳了”,一顿廉价早餐,让母亲发小作文

“太窒息了,我要是孩子直接跳了”,一顿廉价早餐,让母亲发小作文

熙熙说教
2026-10-12 13:43:52
2026-10-13 19:36:49
moonfdd incentive-icons
moonfdd
福大大架构师每日一题
1511文章数 83关注度
往期回顾 全部

科技要闻

扎克伯格宣布追上OpenAI!Meta新模型亮相

头条要闻

重庆市原市长黄奇帆被查

头条要闻

重庆市原市长黄奇帆被查

体育要闻

走调的歌声里全是感情 最好的郑钦文尚未登场

娱乐要闻

谭松韵亲自解答兰香结局遗憾

财经要闻

"黑医师"产业链调查:不学医竟能"拿证"

汽车要闻

平台可以共享 设计不能趋同:Stellantis的六个新答案

态度原创

教育
房产
时尚
手机
军事航空

教育要闻

海洋素养活动丨威海:海洋素养大比拼

房产要闻

巨无霸来了!海口百亿大盘,正式动工!

彩毛衣+小黑裤,超显气色的!

手机要闻

荣耀WIN2系列首秀:行业首创双风扇涡轮散热 WIN平板同台亮相

军事要闻

胡塞武装持续发动袭击 沙特王储被指辗转多个地堡宫殿

无障碍浏览 进入关怀版