刷题打卡 “小c的mex集合“| 豆包MarsCode AI刷题

116 阅读4分钟

1. 题目描述

小C拿到了一个空集,她准备进行以下操作:将区间 [l, r] 内的每个整数添加进集合。每次操作后,她需要输出当前集合的 mex。

定义: 集合的 mex(最小排除值)是指集合中最小的未出现的非负整数。

输入:

  • 整数 q 表示操作的次数。
  • 一个包含 q 个查询的列表 queries,每个查询是一个列表 [l, r],表示在集合中添加区间 [l, r] 中的所有整数。

输出:

  • 一个列表,包含每次操作后集合的 mex。

2. 题目解析

mex 的含义:

  • mex 是最小的非负整数,且不在当前集合中。例如,如果集合是 {0, 1, 3, 4},那么 mex 就是 2,因为 01 已经出现了,2 是最小的未出现的数字。

思考过程:

  1. 集合维护: 我们用一个集合 current_set 来维护当前集合的元素。
  2. mex 更新: 每次加入新元素时,我们需要重新计算 mex。最直观的做法是从当前 mex 开始检查,如果 mex 不在集合中,则返回当前 mex,否则递增直到找到一个未出现的数字。
  3. 高效性: 在每次操作时,需要快速更新集合并计算 mex,尤其是当加入的区间范围较大时,我们需要确保方法的效率。

3. 思考过程

为了实现高效的 mex 计算,我们可以采取以下策略:

  1. 集合存储: 使用 Python 的 set 数据结构,因为 set 支持高效的元素查找和插入。
  2. mex 计算: 初始时,mex 从 0 开始,我们每次操作后检查 mex 是否在集合中。如果在集合中,我们递增 mex 并检查新的 mex 是否存在,直到找到一个不在集合中的数字。
  3. 批量加入区间: 对于每个查询 [l, r],我们需要将区间内的所有整数添加到集合中。由于区间可能较大,直接遍历区间并将每个数字加入集合。

4. 解题代码

初始化变量和集合

result = []  # 用于存储每次操作后的 mex
current_mex = 0  # 当前的 mex,初始值为 0
current_set = set()  # 用于存储当前集合
  • result 用来存储每次操作后的 mex
  • current_mex 用来追踪当前的 mex,初始化为 0
  • current_set 用来存储当前集合中的元素,使用 set 来确保查找和插入的高效性。

遍历每个查询,更新集合并计算 mex

for l, r in queries:
    # 将区间 [l, r] 内的每个数字添加到 current_set 中
    for num in range(l, r + 1):
        current_set.add(num)
    
    # 更新 mex,直到找到一个未出现在集合中的 mex
    while current_mex in current_set:
        current_mex += 1
    
    # 记录当前的 mex
    result.append(current_mex)
  • 遍历每个查询 [l, r]
  • 对于每个查询中的区间 [l, r],将区间内的所有整数添加到 current_set 中。
  • 然后,我们通过 while current_mex in current_set: 循环检查并更新 mex。如果当前的 mex 已在集合中,递增 mex 直到找到一个不在集合中的最小值。
  • 每次更新 mex 后,将其添加到 result 列表中。

返回结果

return result
  • 返回最终存储所有 mex 的 result 列表。

测试代码

if __name__ == '__main__':
    # 测试用例
    print(solution(4, [[1, 3], [7, 8], [0, 5], [3, 6]]) == [0, 0, 6, 9])
    print(solution(3, [[0, 2], [3, 4], [6, 10]]) == [3, 5, 5])
    print(solution(2, [[2, 5], [7, 9]]) == [0, 0])
  • 测试了三个不同的测试用例,确保每次操作后 mex 的计算符合预期。

5. MarsCode 帮助了我什么?

MarsCode 在我解决这个问题的过程中提供了以下几方面的帮助:

  1. 优化数据结构选择: 我最初使用了 list 来存储集合元素,而 MarsCode 推荐我使用 set,因为 set 的查找和插入操作更高效,特别是在集合较大时。
  2. mex 计算的优化: 在最初的思路中,我是通过每次从 0 开始检查整个集合中的元素来计算 mex,效率较低。MarsCode 提供了递增 mex 的思路,避免了不必要的检查,从而提高了效率。
  3. 代码重构和简化: MarsCode 使我意识到代码可以通过简化循环和移除冗余部分来优化,从而使代码更加简洁易懂。

6. 总结

通过这道题,我深刻理解了如何在动态更新集合的过程中计算 mex。在面对类似问题时,选择合适的数据结构和优化算法是至关重要的。此外,MarsCode 提供的帮助让我更加高效地解决了问题,优化了我的代码设计和实现。通过这一过程,我不仅提升了自己的编程能力,也学到了如何更好地优化解决方案,提高效率。

希望在未来,能够借助 MarsCode 继续解决更多复杂的编程问题,不断提升自己!