计算从位置x到y的最少步数 | 豆包MarsCode AI刷题

169 阅读5分钟

今天带来做题分享!

一、分析问题关键要素

  • 已知起始位置 x 和目标位置 y,我们的任务是找到从 x 到 y 满足特定移动规则下的最少步数。
  • 移动规则为每步可以将当前位置增加或减少,步长是上一步的 -1、+0 或 +1,且首末两步的步长必须是 1。

二、确定解题方向

可以考虑使用动态规划或者贪心算法的思想来解决这个问题,下面分别阐述这两种思路。

三、动态规划思路

第一步:定义状态

设 dp[i][j] 表示从起始位置 x 经过 i 步到达位置 j 所需要的最少步数。其中 i 的取值范围从 0 开始,直到一个足够大的值(可根据 x 和 y 的差值大致估算,比如 abs(x - y) 的若干倍),j 的取值范围覆盖可能到达的所有整数位置(可根据起始位置 x 和移动规则大致确定一个范围)。

第二步:初始化状态

  • 当 i = 0 时,也就是还未开始移动,此时 dp[0][x] = 0,因为在起始位置不需要移动步数。

第三步:状态转移方程推导

对于每一步 ii > 0)和每一个可能到达的位置 j

  • 考虑上一步的三种可能步长情况:

    • 如果上一步步长为 -1,那么上一步的位置为 j + 1,此时更新 dp[i][j] 为 min(dp[i][j], dp[i - 1][j + 1] + 1),这里的 +1 表示从 j + 1 位置移动到 j 位置需要一步。
    • 如果上一步步长为 +0,那么上一步的位置为 j,此时更新 dp[i][j] 为 min(dp[i][j], dp[i - 1][j] + 1)
    • 如果上一步步长为 +1,那么上一步的位置为 j - 1,此时更新 dp[i][j] 为 min(dp[i][j], dp[i - 1][j - 1] + 1)

第四步:最终答案获取

不断填充 dp 数组,直到找到 dp[i][y] 有值(即找到了从起始位置 x 经过 i 步到达目标位置 y 的情况),此时的 i 就是从 x 到 y 的最少步数。

四、贪心算法思路

第一步:分析移动趋势

观察起始位置 x 和目标位置 y 的关系,判断整体的移动趋势是应该增加还是减少。如果 y > x,则整体趋势是增加;如果 y < x,则整体趋势是减少。

第二步:确定贪心策略

  • 首步和末步的步长必须是 1,所以先确定首步的方向,朝着目标位置迈出第一步,步长为 1。
  • 从第二步开始,尽量保持步长不变,朝着目标位置持续移动,直到距离目标位置只剩下一步时,再迈出末步,步长为 1。

第三步:计算步数

按照上述贪心策略,计算出从 x 到 y 的步数。具体计算方式如下:

  • 设已经移动的步数为 step,初始化为 0。

  • 先迈出首步,根据 x 和 y 的关系确定首步方向,步长为 1,此时 step = 1

  • 然后,在中间过程中,如果 y > x 且当前位置小于 y,或者 y < x 且当前位置大于 y,则保持步长不变继续移动,每移动一次 step++

  • 当距离目标位置只剩下一步时(即 abs(current_position - y) == 1),迈出末步,步长为 1,此时 step++

最终的 step 值就是从 x 到 y 的最少步数。

通过以上动态规划或贪心算法的思路,都可以尝试求出从 x 到 y 的最少步数。在实际应用中,可以根据具体情况选择更合适的方法,一般来说,如果数据规模较小,贪心算法可能更简洁高效;如果数据规模较大且需要精确求解,动态规划可能更可靠。

部分代码 def solution(x_position, y_position): # Please write your code here return -2

心得

通过解决这道题,我对动态规划和贪心算法这两种常见的算法策略有了更深入的理解和实践体验。

动态规划方面

  • 定义状态是关键的第一步。在本题中,通过设置 dp[i][j] 来表示经过特定步数到达特定位置所需的最少步数,清晰地将问题的两个关键维度 —— 步数和位置进行了量化和记录。这让我明白,准确地定义状态能够将复杂的问题转化为可逐步求解的子问题,为后续推导状态转移方程奠定基础。

  • 推导状态转移方程需要仔细考虑各种可能的情况。对于本题,要顾及上一步的三种不同步长情况,分别计算并更新当前状态的最少步数。这一过程不仅考验对问题规则的细致把握,也锻炼了逻辑推理能力,让我更加熟练地掌握了如何从已知的子问题状态推导出当前状态的最优解。

贪心算法方面

  • 确定合适的贪心策略是核心。在本题中,根据首末两步步长必须为 1 以及整体移动趋势来制定贪心策略,即先迈出符合要求的首步,然后尽量保持步长不变朝着目标移动,最后再迈出末步。这使我认识到,贪心算法的关键在于找到一种在每一步都看似最优的决策方式,虽然它不一定能保证全局最优,但在某些情况下能够快速得到较为满意的结果。

  • 分析问题的整体特征以制定策略也很重要。通过观察起始位置和目标位置的关系来判断移动趋势,进而确定具体的移动步骤,这让我学会了从宏观角度审视问题,提取关键信息来指导贪心策略的制定。