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

55 阅读3分钟

61. 阿D的最佳飞行路线探索

在航班规划和航空管制中,飞行路线的优化是一个常见的挑战。假设小C和他的领导小F计划一次飞行,但由于严格的航空管制,飞机只能按照特定的规则飞行:飞机只能飞往相邻的机场,或者飞往同一航空公司管理的其他机场。为了减少起飞次数,小C需要找出最优的飞行路线。我们将通过题目给出的规则和要求,探讨如何通过算法有效地解决这一问题。

问题描述

给定一个整数数组 airports,其中每个元素表示一个机场,元素的值代表机场所隶属的航空公司。我们从起点机场(数组的第一个元素)出发,目标是飞到终点机场(数组的最后一个元素)。飞机可以:

  1. 直接飞往相邻的机场;
  2. 或者如果两个机场属于同一航空公司,飞机也可以直接飞往。

目标:求出最小的起飞次数,即从起点到终点所需的最少飞行段数。

问题分析

思路解析

这个问题的核心是寻找从起点机场到终点机场的最短路径。由于飞行规则允许相邻机场直接飞行,且相同航空公司的机场也可以直接飞行,因此这个问题可以建模为图的最短路径问题。

1. 图的建模

  • 每个机场可以视为图中的一个节点。
  • 相邻机场可以视为图中的边,且权重为 1(即一次飞行)。
  • 相同航空公司管理的机场之间也可以视为有边连接的节点。

2. 图的遍历

  • 为了找到从起点到终点的最短路径,我们可以使用广度优先搜索(BFS),因为 BFS 可以保证我们找到的是最短路径。
  • 在 BFS 中,我们将每个机场视为一个节点,从起点机场开始,逐步扩展到相邻机场和同一航空公司管理的其他机场。

3. BFS搜索

  • 使用队列 queue 来实现 BFS,队列中的每个元素包含一个机场的索引和当前飞行次数。
  • 使用 visited 集合来记录已经访问过的机场,避免重复访问。
  • 每次从队列中取出一个机场,尝试飞往相邻机场或相同航空公司管理的机场。
  • 如果到达终点机场,则返回当前飞行次数。

优化考虑

  • 时间复杂度:BFS 在最坏情况下遍历所有节点和边。由于机场的数量是 n,最多有 n 个节点,且每个机场最多会与其他机场有连接,因此 BFS 的时间复杂度是 O(n)。
  • 空间复杂度:BFS 需要一个队列和一个 visited 集合,空间复杂度为 O(n)。

实现

我们将使用广度优先搜索(BFS)来实现最短路径的求解。代码如下:

from collections import defaultdict, deque

def solution(airports):
    n = len(airports)
    if n <= 1:
        return 0

    # 构建航空公司连接图
    company_airports = defaultdict(list)
    for i, airport in enumerate(airports):
        company_airports[airport].append(i)

    # BFS搜索最短路径
    queue = deque([(0, 0)])  # (当前机场索引, 已飞行次数)
    visited = {0}  # 记录已访问的机场

    while queue:
        curr_airport, flights = queue.popleft()

        # 如果到达终点,返回飞行次数
        if curr_airport == n - 1:
            return flights

        # 尝试所有可能的下一个机场
        next_airports = set()

        # 1. 相邻机场
        if curr_airport > 0:
            next_airports.add(curr_airport - 1)
        if curr_airport < n - 1:
            next_airports.add(curr_airport + 1)

        # 2. 相同航空公司的机场
        curr_company = airports[curr_airport]
        next_airports.update(company_airports[curr_company])

        # 遍历所有可能的下一个机场
        for next_airport in next_airports:
            if next_airport not in visited:
                visited.add(next_airport)
                queue.append((next_airport, flights + 1))

    return -1  # 如果无法到达终点