【202】小M的订单编号问题 | 豆包MarsCode AI刷题

66 阅读4分钟

问题描述

在商家的订单编号系统中,每次发起订单时,编号会递增。当编号达到上限 m 时,会从 1 重新开始编号。给定编号上限 m 和第 x 个订单,要求计算出第 x 个订单的编号。

例如:

  • 当 m = 2 和 x = 3 时,订单编号为 1,因为编号会循环。
  • 当 m = 5 和 x = 17 时,订单编号为 2,因为 17 除以 5 的余数是 2。

我们需要实现一个函数 solution(m: int, x: int) 来根据给定的 mx 输出第 x 个订单的编号。

解题思路

我们可以通过观察题目给出的样例和具体描述,总结出以下几个要点:

  1. 编号递增和循环回到1:编号从1开始,每次递增,直到达到最大值 m,然后重新从1开始。

  2. 余数运算:编号的递增实际上是一个循环的过程。当编号超过 m 时,我们可以通过对 x 取余来确定其当前的编号:

    • 若 x % m == 0,说明当前编号正好是 m
    • 否则,编号就是 x % m

例如,若 m = 5x = 17,那么 17 % 5 = 2,说明第17个订单的编号为2。

解题步骤

根据解题思路,我们可以总结出以下的解题步骤:

  1. 初始化:读取输入的 m 和 x
  2. 判断是否需要循环:如果 x 小于或等于 m,则直接返回 x,因为此时编号不会循环。
  3. 计算余数:如果 x 大于 m,则计算 x % m,并根据余数来确定编号。
  4. 处理余数为0的特殊情况:如果余数为 0,则编号应为 m,即循环回到最大编号。

解题代码

pythonCopy Code
def solution(m: int, x: int) -> int:
    # 如果x小于或等于m,那么订单编号就是x
    if x <= m:
        return x
    # 否则,我们需要计算循环后的编号
    else:
        # 计算x除以m的余数
        remainder = x % m
        # 如果余数为0,说明编号回到了1,否则就是余数本身
        return remainder if remainder != 0 else m

if __name__ == '__main__':
    # 测试样例
    print(solution(2, 3) == 1)
    print(solution(5, 17) == 2)
    print(solution(8, 2) == 2)
    print(solution(4, 4) == 4)

解题思路详细解析

1. 编号的递增规则

订单编号从 1 开始,每次递增,达到上限 m 后重新开始编号。这意味着编号遵循一个周期性的规律。我们可以利用这个规律来通过数学计算确定编号,而不需要模拟每个订单的编号过程。关键在于理解这个规律并应用余数运算。

2. 余数运算的运用

编号的循环本质上是对 m 取余。比如:

  • 当 m = 5 时,编号依次为:1, 2, 3, 4, 5,然后再从1开始。
  • 如果 x = 17,可以通过 17 % 5 = 2 得出第17个订单的编号是 2。

这个余数运算直接告诉我们订单编号在一个周期中的位置。

3. 余数为0的特殊处理

x % m == 0 时,编号应为 m,因为此时编号已经到了最大值,循环回到最大编号。举个例子,当 m = 5 时,第 5 个、第 10 个、第 15 个订单的编号都应为 5。

4. 时间和空间优化

此问题可以通过一个简单的数学运算来解决,不需要复杂的循环或数据结构,因此时间复杂度为 O(1),空间复杂度也是 O(1),非常高效。

复杂度分析

1. 时间复杂度

解决此问题只需要进行常数次运算。具体而言,只需要判断 x <= m 和计算 x % m。这两步操作的时间复杂度都是常数级别的。因此,总的时间复杂度为 O(1)

2. 空间复杂度

我们只需要存储一些变量来保存输入值和计算结果,因此空间复杂度为 O(1),即常数空间。

总结

通过利用编号的周期性特征,我们能够快速地确定任意订单的编号。该算法的核心在于对 x 取余来找到其在周期中的位置,并通过简单的条件判断处理特殊情况(如余数为 0)。这一方法具有很高的效率,能够快速解决问题,并且在时间和空间复杂度上都表现出色。