豆包MarsCode AI 刷题记录5

5 阅读4分钟

小M有一个独特的方式来收拾家中的盘子。每次用餐后,他会将盘子按照他们的序号顺序叠放。盘子的序号都是唯一的整数,并且在收拾前就是递增的。小M的叠放规则是,每一堆盘子的序号都是连续递增的,并且至少包含3个盘子。需要编写程序帮助小M确定盘子的叠放方式。 例如,输入的盘子序号是 [-3, -2, -1, 2, 10, 15, 16, 18, 19, 20],按照小M的规则,连续递增序列 -3, -2, -1 可以叠在一起表示为 -3--1,而 18, 19, 20 可以叠在一起表示为 18-20。不满足连续递增至少3个的,如 2, 10, 15, 16 都应单独列出。

学习笔记:如何根据条件整理盘子的叠放方式

一、问题分析

小M需要将家中的盘子按照序号顺序叠放,并且遵循以下规则:

  1. 每一堆盘子的序号必须是连续递增的。
  2. 每堆盘子至少包含3个盘子。
  3. 盘子序号为唯一整数,且初始序号递增。

我们的目标是根据给定的盘子序号,确定如何将盘子整理成符合规则的叠放方式。

二、如何设计解法

我们可以从问题的要求出发,设计以下的解决步骤:

  1. 遍历盘子序号:我们需要遍历盘子序号列表,寻找连续递增的子序列。
  2. 分组:将连续递增的盘子组合成一组。如果某一组的长度大于等于3,则可以将其合并为一个范围表示(如 -3--1),否则就单独列出。
  3. 输出:最终将整理好的结果按照要求的格式输出。
2.1 分组逻辑
  • 如果两个盘子是连续递增的,则它们可以归为一组。
  • 如果一个盘子与下一个盘子不连续,则表示当前一组已经结束,可以输出并开始新的组。
  • 对于每一组,如果它包含的盘子个数大于或等于3个,则用范围表示(如 start-end),否则每个盘子单独列出。

三、代码实现

def solution(plates):
    # 将盘子序号按升序排列
    plates = sorted(plates)
    
    # 初始化结果列表和当前连续序列的开始位置
    result = []
    n = len(plates)
    i = 0
    
    while i < n:
        # 记录当前连续序列的起始盘子序号
        start = i
        # 找到当前连续序列的末尾
        while i + 1 < n and plates[i] + 1 == plates[i + 1]:
            i += 1
        
        # 判断序列长度
        if i - start + 1 >= 3:
            # 序列长度大于等于3,使用范围表示
            result.append(f"{plates[start]}-{plates[i]}")
        else:
            # 序列长度小于3,单独列出
            result.extend(str(plates[j]) for j in range(start, i + 1))
        
        # 移动到下一个序列的起始位置
        i += 1
    
    # 返回结果字符串
    return ",".join(result)

# 测试样例
if __name__ == "__main__":
    print(solution([-3, -2, -1, 2, 10, 15, 16, 18, 19, 20]) == "-3--1,2,10,15,16,18-20")
    print(solution([-6, -3, -2, -1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11, 14, 15, 17, 18, 19, 20]) == "-6,-3-1,3-5,7-11,14,15,17-20")
    print(solution([1, 2, 7, 8, 9, 10, 11, 19]) == "1,2,7-11,19")

四、代码解释

  1. 排序plates = sorted(plates):首先对盘子序号进行升序排序,这样可以确保我们能够依次找到连续的盘子序号。
  2. 查找连续递增的子序列: 使用 while i + 1 < n and plates[i] + 1 == plates[i + 1] 来判断当前盘子是否与下一个盘子连续。如果是,则继续增加序列的长度。如果不是,则结束当前序列的查找。
  3. 判断序列长度if i - start + 1 >= 3:如果当前连续序列的长度大于或等于3,就将其按范围表示(如 -3--1);否则,将每个盘子序号单独列出。
  4. 返回结果",".join(result):最后将结果列表中的元素用逗号连接成一个字符串,并返回。

五、复杂度分析

  1. 时间复杂度

    • 排序操作的时间复杂度是 O(n log n),其中 n 是盘子的数量。
    • 遍历整个列表并进行分组操作的时间复杂度是 O(n)
    • 因此,总的时间复杂度是 O(n log n),其中排序是主要的时间开销。
  2. 空间复杂度

    • 我们需要额外的空间来存储结果列表,空间复杂度为 O(n),因为在最坏情况下,每个盘子可能都需要单独列出。