阿D的最佳飞行路线探索 | 豆包MarsCode AI 刷题

131 阅读4分钟

问题背景

给定一个机场列表 airports,其中每个元素表示一个机场所属的航空公司编号。你需要从第一个机场出发,到达最后一个机场。每次起飞可以选择以下两种方式之一:

  • 飞往相邻的机场(即前一个或后一个机场)。
  • 飞往同一航空公司的其他机场。

目标是找出从第一个机场到最后一个机场所需的最小起飞次数。

解决思路

这是一个典型的最短路径问题,可以通过广度优先搜索(BFS)来解决。BFS适用于寻找无权图中的最短路径问题,因为它会逐层扩展节点,确保最先到达终点的路径是最短的。

具体步骤

  1. 初始化

    • 使用一个队列来存储待处理的机场位置。
    • 使用一个集合来记录已经访问过的机场,避免重复访问。
    • 使用一个字典来存储每个航空公司管理的所有机场的索引,以便快速查找。
  2. 构建航空公司索引字典

    • 遍历 airports 列表,将每个机场的索引添加到对应的航空公司字典中。
  3. 开始 BFS

    • 将起点机场(索引 0)加入队列,并标记为已访问。
    • 初始化起飞次数 takeoffs 为 0。
  4. 处理队列中的每个机场

    • 对于队列中的每个机场,尝试所有可能的下一步:
      • 检查相邻的机场(前一个和后一个机场)。
      • 检查同一航空公司的其他机场。
    • 如果找到终点机场(索引 len(airports) - 1),返回当前的起飞次数。
    • 如果没有找到终点机场,将所有未访问过的下一站机场加入队列并标记为已访问。
  5. 增加起飞次数

    • 每次处理完当前层的所有机场后,增加起飞次数。
  6. 结束条件

    • 如果队列为空且未找到终点机场,理论上不会发生,因为题目保证有解。

Python 实现

以下是详细的 Python 实现代码:

from collections import deque, defaultdict
def solution(airports):
    if len(airports) <= 1:
            return 0
        
    # 创建一个字典来存储每个航空公司管理的所有机场索引
    airline_dict = defaultdict(list)
    for index, airline in enumerate(airports):
        airline_dict[airline].append(index)
    
    # 初始化队列和访问集合
    queue = deque([0])
    visited = set([0])
    takeoffs = 0
    
    while queue:
        # 遍历当前层的所有机场
        for _ in range(len(queue)):
            current_airport = queue.popleft()
            
            # 如果到达了最后一个机场,则返回起飞次数
            if current_airport == len(airports) - 1:
                return takeoffs
            
            # 获取当前机场的所有可能下一个机场
            next_airports = []
            # 添加相邻机场
            if current_airport - 1 >= 0 and current_airport - 1 not in visited:
                next_airports.append(current_airport - 1)
            if current_airport + 1 < len(airports) and current_airport + 1 not in visited:
                next_airports.append(current_airport + 1)
            # 添加相同航空公司的其他机场
            for airport_index in airline_dict[airports[current_airport]]:
                if airport_index != current_airport and airport_index not in visited:
                    next_airports.append(airport_index)
            
            # 将所有未访问过的下一站加入队列并标记为已访问
            for airport in next_airports:
                visited.add(airport)
                queue.append(airport)
        
        # 完成一层遍历后,增加起飞次数
        takeoffs += 1
    
    # 如果没有找到路径到达终点,理论上不会发生,因为题目保证有解
    return -1
if __name__ == "__main__":
    #  You can add more test cases here
    print(solution([10,12,13,12,14]) == 3 )
    print(solution([10,11,12,13,14]) == 4 )

解释

  1. 初始化

    • airline_dict 存储每个航空公司管理的所有机场索引。
    • queue 存储待处理的机场索引,初始包含起点机场。
    • visited 记录已访问的机场索引,防止重复访问。
    • takeoffs 记录起飞次数,初始为 0。
  2. BFS 过程

    • 每次从队列中取出一个机场,检查是否到达终点。
    • 如果未到达终点,获取所有可能的下一站机场(相邻机场和同一航空公司的其他机场)。
    • 将未访问过的下一站机场加入队列并标记为已访问。
    • 每处理完一层机场后,增加起飞次数。
  3. 返回结果

    • 当找到终点机场时,返回当前的起飞次数。
    • 如果队列为空且未找到终点机场,返回 -1(理论上不会发生)。