“青训营X豆包MarsCode 技术训练营第一课 | 豆包MarsCode AI 刷题”

108 阅读4分钟

问题描述: 小C和领导小F计划飞行,但由于航空管制的限制,飞机只能按特定的路线飞行:飞机只能飞往当前机场的相邻机场或同一家航空公司管理的其他机场。目标是最小化起飞次数,从机场 0 到达机场 n-1。每个机场由数组 airports 表示,其中每个元素是航空公司的编号。

目标: 求最小起飞次数。起飞次数是指需要飞行的步骤数(换乘或飞行的次数)。飞机可以直接飞往相邻机场或同航空公司管理的机场。 思路总结:

使用广度优先搜索(BFS)来找到最短路径。BFS的特点是按层次逐步扩展,能够保证找到最短路径。 BFS的每一步尝试访问相邻机场或同一航空公司的其他机场。 维护一个队列,队列中存储当前机场的位置以及到达该位置的起飞次数。 为了避免重复访问,使用一个 visited 集合来记录已访问的机场。 BFS每次从当前机场扩展: 可以飞到相邻的机场(即 i-1 和 i+1,如果有效)。 也可以飞到同一航空公司管理的其他机场。 如果到达终点机场 n-1,返回当前的起飞次数。 from collections import deque

def solution(airports): n = len(airports) if n == 1: # 如果只有一个机场,直接到达终点,不需要起飞 return 0

# 创建一个字典,存储每个航空公司管理的所有机场索引
airline_dict = {}
for i, airline in enumerate(airports):
    if airline not in airline_dict:
        airline_dict[airline] = []
    airline_dict[airline].append(i)

# BFS初始化,队列中存储的是 (当前机场的索引, 当前起飞次数)
queue = deque([(0, 0)])  # 从机场0出发,起飞次数为0
visited = set([0])  # 记录已访问的机场,初始访问机场0

while queue:
    current, steps = queue.popleft()
    
    # 如果到达终点,返回当前的起飞次数
    if current == n - 1:
        return steps
    
    # 1. 检查相邻的机场(i-1 和 i+1)
    for neighbor in [current - 1, current + 1]:
        if 0 <= neighbor < n and neighbor not in visited:
            visited.add(neighbor)
            queue.append((neighbor, steps + 1))
    
    # 2. 检查同航空公司的机场
    for neighbor in airline_dict.get(airports[current], []):
        if neighbor not in visited:
            visited.add(neighbor)
            queue.append((neighbor, steps + 1))

return -1  # 如果没有找到路径,理论上不会执行到这里

if name == "main": # 测试用例 print(solution([10, 12, 13, 12, 14]) == 3) # 输出 3 print(solution([10, 11, 12, 13, 14]) == 4) # 输出 4 print(solution([7, 7, 7, 8, 9, 7]) == 1) # 输出 1 代码分析 初始化与BFS队列:

首先,我们通过 enumerate 构建了一个 airline_dict 字典,字典的键是航空公司编号,值是该航空公司管理的所有机场的索引列表。 然后,使用广度优先搜索(BFS)来求解最短路径,BFS的队列 queue 初始化为 (0, 0),表示从机场 0 出发,当前起飞次数为 0。 BFS扩展:

每次从队列中取出当前机场 current 和起飞次数 steps。 如果 current 等于终点机场 n-1,则说明到达终点,返回当前的起飞次数。 否则,首先检查当前机场的相邻机场,即 current - 1 和 current + 1(如果有效),并将这些机场加入队列。 其次,检查同一家航空公司管理的机场,并将这些机场加入队列。 终止条件:

BFS会在找到最短路径时立即返回。 如果所有机场都遍历完后仍未找到终点,则返回 -1(理论上不可能出现这种情况,因为题目假设有路径到达终点)。 题目难点与知识点总结 广度优先搜索(BFS):

BFS是解决最短路径问题的经典算法,适用于无权图中的最短路径问题。通过层层扩展,保证了找到的路径是最短的。 图的表示与遍历:

机场之间的连接可以通过相邻机场和同一航空公司管理的机场来表示,因此需要对这些信息进行处理并存储。 使用字典存储每个航空公司对应的机场列表,方便后续遍历。 使用集合记录已访问节点:

为了避免重复访问,使用 visited 集合记录已经访问过的机场。这样可以避免处理已经遍历过的机场,减少无效操作。 对入门同学的学习建议 理解BFS算法:

BFS是一种非常基础且重要的图算法,在解决最短路径问题时尤其常见。建议同学们先理解BFS的基本原理,然后通过实践掌握它的使用。 图的表示方式:

对于图的题目,常见的图的表示方式有邻接矩阵、邻接表、边列表等。在本题中,使用字典存储每个航空公司管理的机场是一个有效的表示方式。 调试技巧:

在写BFS算法时,调试时可以加入一些打印语句,输出当前状态,检查算法是否按预期运行。特别是在处理类似图遍历的问题时,确保每个节点只访问一次。