leetcode
leetcode 2651 ~ 2700
赛车

赛车

难度:

标签:

题目描述

Your car starts at position 0 and speed +1 on an infinite number line. Your car can go into negative positions. Your car drives automatically according to a sequence of instructions 'A' (accelerate) and 'R' (reverse):

  • When you get an instruction 'A', your car does the following:
    • position += speed
    • speed *= 2
  • When you get an instruction 'R', your car does the following:
    • If your speed is positive then speed = -1
    • otherwise speed = 1
    Your position stays the same.

For example, after commands "AAR", your car goes to positions 0 --> 1 --> 3 --> 3, and your speed goes to 1 --> 2 --> 4 --> -1.

Given a target position target, return the length of the shortest sequence of instructions to get there.

 

Example 1:

Input: target = 3
Output: 2
Explanation: 
The shortest instruction sequence is "AA".
Your position goes from 0 --> 1 --> 3.

Example 2:

Input: target = 6
Output: 5
Explanation: 
The shortest instruction sequence is "AAARA".
Your position goes from 0 --> 1 --> 3 --> 7 --> 7 --> 6.

 

Constraints:

  • 1 <= target <= 104

代码结果

运行时间: 77 ms, 内存: 0.0 MB


解释

方法:

这个题解使用BFS(广度优先搜索)的方法来解决问题。具体思路如下: 1. 使用队列 queue 存储当前位置、当前速度以及下一步是否执行 'A' 操作的状态。 2. 使用 visited 集合记录已访问过的状态,避免重复访问。 3. 从初始状态 (0, 1, True) 开始进行BFS搜索。 4. 在每一轮搜索中,取出队列中的所有状态,并对每个状态进行以下操作: - 如果当前状态已经访问过,则跳过。 - 如果当前位置等于目标位置 target,则返回当前的搜索步数 k。 - 如果下一步是 'A' 操作,则更新当前位置和速度。 - 如果下一步是 'R' 操作,则根据当前速度的正负来更新速度。 - 根据更新后的速度和位置,判断是否会超过目标位置: - 如果不会超过,则将新状态加入队列,并标记下一步为 'A'。 - 如果会超过,则将两个新状态都加入队列,分别标记下一步为 'A' 和 'R'。 5. 搜索步数 k 不断递增,直到找到目标位置或队列为空。 6. 返回最终的搜索步数 k。

时间复杂度:

O(target)

空间复杂度:

O(target)

代码细节讲解

🦆
为什么在执行反向操作'R'后,不考虑更新当前位置,只更新速度?
在赛车问题中,执行操作 'R'(反向)的目的是改变赛车的方向,准备下一次加速或减速。根据题目的规则,每次执行 'R' 操作只影响速度的方向,而不直接影响位置。这种设计模拟了真实世界中汽车在改变方向时,虽然方向改变了但位置仍保持不变,只有在随后的加速或减速操作中,位置才会改变。因此,在模拟这个过程时,执行 'R' 操作后只更新速度,不更新位置,以符合题目的逻辑和现实的行为模式。
🦆
在BFS中,如何确保不会因为位置和速度的快速增长而导致内存溢出或性能问题?
在使用BFS处理赛车问题时,确实存在位置和速度快速增长的问题,这可能导致内存使用量增加。为了控制资源使用和提高算法的效率,主要可以采用以下策略:1. 使用 visited 集合来存储已经访问过的状态(位置和速度),避免重复搜索相同状态。2. 限制搜索范围,例如,在状态转移时检查新状态是否有意义(如位置和目标距离过远或速度过大时可剪枝)。3. 在某些情况下,可以通过设置适当的阈值来限制速度或位置的最大值,避免无效的搜索。这些方法可以帮助减少不必要的内存消耗和提升搜索效率。
🦆
对于已访问过的状态,题解仅通过检查是否存在于visited中来避免重复处理。这种方法能否完全防止所有不必要的重复搜索?
使用 visited 集合来记录已访问状态是防止赛车问题中发生重复搜索的常用方法。然而,这种方法主要防止同一状态的精确重复访问。在某些复杂的情况下,尽管不同的搜索路径可能达到相同的状态,但可能存在由于不同操作序列而产生的细微变化,这些变化可能未能通过简单的 visited 检查被识别出来。因此,虽然 visited 集合在大多数情况下能有效减少重复搜索,但它不能完全排除所有重复搜索的可能性,特别是在存在多路径到达同一状态的情况下。为了进一步优化,可以考虑使用更复杂的状态管理策略,如记录到达每个状态的最小步数,进行更细致的状态比较。

相关问题