题目解析(AI刷题39题) | 豆包MarsCode AI刷题

169 阅读3分钟

题目简述

要求整数位置 x 移动到整数位置 y的最小步数,

限制:

  • 每步的移动范围是上一步的 -1,+0 或 +1
  • 首末两步的步长必须是 1

输入:

  • x:起始位置
  • y:目标位置

输出:

  • ans:从 x 到 y 所需的最小步数

代码思路

确定起始和目标位置

首先,代码中通过比较输入的 x_position 和 y_position 的大小来确定起始位置和目标位置。如果 x_position 大于 y_position,则将 x_position 赋给 maxx,y_position 赋给 minn;否则反之。这一步是为了确保后续计算的正确性。

if x_position>y_position:
    maxx=x_position
    minn=y_position
else:
    maxx=y_position
    minn=x_position

计算需要移动的步数

代码计算了需要移动的步数 need,即目标位置和起始位置之间的距离。这个距离即为 maxx - minn。这个步骤是为了确定移动的目标步数的上限。

need=maxx-minn

求解步数的上界

接下来,代码通过求解一个方程 a*(a+1)=need 来得到步数的一个上界 a。这里通过从 0 开始逐个增加 a,直到找到第一个满足 a*(a+1)=need 的整数 a 为止。这个方程的解即为满足移动步数的一个上限。

a=int(pow(need,0.5))
n=a-1

判断最小步数

接着,代码根据上一步得到的 a 进行判断:

  • 如果 a*(a+1) 等于 need,说明恰好可以通过 2a 步到达目标位置,直接返回 2a。
  • 否则,计算余数 rest = need - n*(n+1),其中 n = a-1。这一步计算得到需要额外移动的步数。

在余数 rest 计算出来后,代码进行了如下判断:

  • 如果 rest 能整除 n,说明可以在 2n 步内到达目标位置,返回 2n+1。
  • 否则,计算 n1 = rest // (n+1),并返回 2*n+n1+1。这个过程考虑到了余数无法整除 n 的情况,通过计算 n1 来得到最终的步数。
if (a*(a+1))==need:
    return 2*a
else:
    rest=need-n*(n+1)
    # print(rest,n,2*n)
    ok=rest%n
    # print(rest,n,2*n,ok)
    if(ok==0):
        # print(111111)
        return 2*n+1
    else:
        n1=rest//(n+1)
        # print(111111)
        # print(n1)
        return 2*n+n1+1

复杂度分析

时间复杂度分析

求解步数的上界:

  • 在代码中,通过求解 a*(a+1)=need 这个方程来得到步数的一个上界 a。这一步需要从 0 开始逐个增加 a 直到找到满足条件的整数 a。
  • 因为 a*(a+1)=need 是一个二次方程,最坏情况下需要遍历所有可能的 a 值。所以这一步的时间复杂度为 O(sqrt(need))。

判断最小步数:

  • 在判断最小步数的部分,需要计算余数 rest = need - n*(n+1),其中 n = a-1。然后根据 rest 是否能整除 n 来确定最小步数。
  • 这一步的时间复杂度取决于对余数的计算和判断操作,因为这些操作的复杂度不会超过 O(sqrt(need)),所以可以近似看作是 O(1)

空间复杂度分析

算法中使用了几个整数型变量来存储计算中的临时结果,比如 maxx、minn、need、a、n、rest、ok、n1 等。

这些变量的空间占用是常数级的,不随输入规模变化,因此对于这些变量的空间复杂度为 O(1)