这个题解使用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)
class Solution:
def racecar(self, target: int) -> int:
queue = collections.deque([(0, 1, True)]) # 初始状态为位置0,速度1,下一步操作为 'A'
visited = set() # 记录已访问过的状态
k = 0 # 搜索步数
while queue:
size = len(queue)
for _ in range(size):
curr_pos, curr_spead, if_A = queue.popleft()
if (curr_pos, curr_spead, if_A) in visited: # 如果当前状态已访问过,则跳过
continue
visited.add((curr_pos, curr_spead, if_A)) # 将当前状态标记为已访问
if curr_pos == target: # 如果到达目标位置,则返回搜索步数
return k
if if_A: # 如果下一步操作为 'A'
curr_pos += curr_spead # 更新位置
curr_spead *= 2 # 更新速度
else: # 如果下一步操作为 'R'
if curr_spead > 0: # 如果当前速度为正,则变为-1
curr_spead = -1
else: # 如果当前速度为负,则变为1
curr_spead = 1
if ((curr_spead > 0 and curr_pos + curr_spead < target) # 如果速度为正且下一步不会超过目标位置
or (curr_spead < 0 and curr_pos + curr_spead > target)): # 或速度为负且下一步不会超过目标位置
queue.append((curr_pos, curr_spead, True)) # 将新状态加入队列,下一步操作为 'A'
else:
queue.append((curr_pos, curr_spead, True)) # 将新状态加入队列,下一步操作为 'A'
queue.append((curr_pos, curr_spead, False)) # 将新状态加入队列,下一步操作为 'R'
k += 1 # 搜索步数加1
return k