题目解析-叠盘子顺序(python)

44 阅读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有一个独特的盘子叠放规则:每次叠放的盘子序号必须是连续递增的,且至少包含 3 个盘子。如果不满足连续递增 3 个盘子的条件,则每个盘子应单独列出。我们需要根据这些规则生成一个符合要求的字符串表示盘子的叠放方式。

解题思路

  1. 遍历盘子序号:首先,我们需要遍历盘子的序号,找出所有连续的递增序列。
  2. 标记连续序列:当我们找到至少 3 个连续递增的盘子时,将其合并为一个范围(如 -3--1)。如果不满足 3 个连续盘子的条件,则将该盘子单独列出。
  3. 拼接结果:将所有符合条件的盘子序号或者范围按照逗号拼接成字符串。

步骤细化

  1. 初始化:我们需要一个空列表来保存结果,遍历盘子序号时,我们需要一个临时列表来存储当前的连续盘子。
  2. 判断连续性:在遍历过程中,检查当前盘子与上一个盘子是否连续。如果是连续的,就继续将其添加到当前的序列中。
  3. 判断序列长度:一旦遇到非连续的盘子,就检查当前的序列是否满足最少 3 个盘子的条件。如果满足,就将其转换为一个范围(如 -3--1)。如果不满足,则将其单独列出。
  4. 最终拼接:处理完所有盘子后,将所有的范围和单独的盘子拼接成一个字符串。

代码实现

def solution(plates: list[int], n: int) -> str:
    result = []  # 存储最终的结果
    temp = []  # 用来存储当前连续的盘子序列

    for i in range(n):
        # 如果当前 temp 为空,或者与 temp 最后一个盘子连续,加入 temp
        if not temp or plates[i] == temp[-1] + 1:
            temp.append(plates[i])
        else:
            # 如果连续序列长度 >= 3,加入范围;否则加入单独的数字
            if len(temp) >= 3:
                result.append(f"{temp[0]}--{temp[-1]}")
            else:
                result.extend(map(str, temp))  # 不满足条件时将所有元素单独列出
            temp = [plates[i]]  # 开始新的连续序列

    # 处理最后一个序列
    if len(temp) >= 3:
        result.append(f"{temp[0]}--{temp[-1]}")
    else:
        result.extend(map(str, temp))

    # 返回最终结果
    return ",".join(result)

# 测试案例
print(solution([-3, -2, -1, 2, 10, 15, 16, 18, 19, 20], 10))  # 输出: "-3--1,2,10,15,16,18--20"

代码解释

  1. 遍历盘子序号

    • temp 用来临时存储当前连续的盘子序列。
    • 如果当前盘子与 temp 的最后一个盘子是连续的(即当前盘子的序号是前一个盘子的序号 + 1),则将当前盘子加入 temp
    • 否则,将 temp 中的盘子序列转为字符串并加入结果 result 中。如果该序列长度小于 3,则单独列出每个盘子;如果大于等于 3,则将其转为范围形式(例如 -3--1)。
  2. 处理最后一个序列

    • 循环结束后,最后一个序列还没有被加入结果中,因此需要额外处理一次。
  3. 返回结果

    • 最后,将所有的结果使用逗号连接起来并返回。

复杂度分析

  • 时间复杂度:O(n),其中 n 是盘子序号的个数。我们只需遍历一次盘子序号列表。
  • 空间复杂度:O(n),因为我们需要存储每个盘子序号的范围或单独列出的盘子。

测试案例

  1. 测试用例 1

    print(solution([-3, -2, -1, 2, 10, 15, 16, 18, 19, 20], 10))  # 输出: "-3--1,2,10,15,16,18--20"
    
    • 解释:序号 -3, -2, -1 连续,可以合并为 -3--1;序号 18, 19, 20 连续,可以合并为 18--20;其他序号不满足连续条件。
  2. 测试用例 2

    print(solution([1, 2, 3, 4, 5], 5))  # 输出: "1--5"
    
    • 解释:所有盘子序号连续,可以合并为一个范围 1--5
  3. 测试用例 3

    print(solution([1, 3, 4, 5], 4))  # 输出: "1,3--5"
    
    • 解释:序号 3, 4, 5 连续,可以合并为 3--5,其他序号单独列出。
  4. 测试用例 4

    print(solution([1, 2], 2))  # 输出: "1,2"
    
    • 解释:没有连续的盘子序号,所以每个盘子都单独列出。

通过这个实现,我们能够根据小M的规则高效地处理盘子的叠放顺序。