61. 阿D的最佳飞行路线探索
在航班规划和航空管制中,飞行路线的优化是一个常见的挑战。假设小C和他的领导小F计划一次飞行,但由于严格的航空管制,飞机只能按照特定的规则飞行:飞机只能飞往相邻的机场,或者飞往同一航空公司管理的其他机场。为了减少起飞次数,小C需要找出最优的飞行路线。我们将通过题目给出的规则和要求,探讨如何通过算法有效地解决这一问题。
问题描述
给定一个整数数组 airports,其中每个元素表示一个机场,元素的值代表机场所隶属的航空公司。我们从起点机场(数组的第一个元素)出发,目标是飞到终点机场(数组的最后一个元素)。飞机可以:
- 直接飞往相邻的机场;
- 或者如果两个机场属于同一航空公司,飞机也可以直接飞往。
目标:求出最小的起飞次数,即从起点到终点所需的最少飞行段数。
问题分析
思路解析
这个问题的核心是寻找从起点机场到终点机场的最短路径。由于飞行规则允许相邻机场直接飞行,且相同航空公司的机场也可以直接飞行,因此这个问题可以建模为图的最短路径问题。
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 # 如果无法到达终点