这是一道中等难度题目,题目如下
问题描述
小C和他的领导小F计划一次飞行,但由于严格的航空管制,他们的飞机仅能按特定的路线飞行:飞机只能飞往当前机场的相邻机场或相同航空公司管理的机场。为了减少起飞次数,小C需要制定最优的飞行路线。机场由一个数组airports标识,其中:
- 数组每个元素代表一个独特的机场,元素的值代表不同的航空公司。
airports[0]为起点,airports[airports.length - 1]为终点。- 假设小C当前在机场
i,那么i - 1和i + 1(如果存在)代表邻近机场,飞机可以直接前往。 - 如果在机场
i,且存在airports[i] == airports[j],则机场i和机场j同属一家航空公司,可直接飞往。
求最小起飞次数。
测试样例
样例1:
输入:
airports = [10, 12, 13, 12, 14]输出:3
样例2:
输入:
airports = [10, 11, 12, 13, 14]输出:4
样例3:
输入:
airports = [7, 7, 7, 8, 9, 7]输出:1
解题思路:
问题理解
-
目标:
- 需要找到从起点机场到终点机场的最小起飞次数。
- 飞机可以从当前机场飞往相邻机场(即
i - 1和i + 1),或者飞往同一家航空公司管理的其他机场。
-
约束条件:
- 机场由一个数组
airports表示,数组中的每个元素代表一个机场,元素的值代表不同的航空公司。 airports[0]是起点,airports[airports.length - 1]是终点。
- 机场由一个数组
数据结构选择
-
图的表示:
- 可以将机场视为图中的节点,相邻机场和同一家航空公司管理的机场视为节点之间的边。
- 使用 BFS(广度优先搜索)来寻找最短路径,因为 BFS 可以保证在无权图中找到最短路径。
-
航空公司映射:
- 使用字典(
defaultdict)来存储同一家航空公司管理的机场列表,这样可以快速查找同一家航空公司管理的其他机场。
- 使用字典(
算法步骤
-
初始化:
- 创建一个队列
queue用于 BFS,初始时将起点机场加入队列。 - 创建一个集合
visited用于记录已访问的机场,避免重复访问。
- 创建一个队列
-
BFS 过程:
- 从队列中取出一个机场,检查是否到达终点机场。
- 如果未到达终点,则探索当前机场的相邻机场和同一家航空公司管理的机场。
- 将未访问的相邻机场和同航空公司管理的机场加入队列,并标记为已访问。
-
边界条件:
- 处理特殊情况,如只有一个机场的情况。
代码实现: from collections import deque, defaultdict
def solution(airports): n = len(airports) if n == 1: return 0
airline_map = defaultdict(list)
for i, airline in enumerate(airports):
airline_map[airline].append(i)
queue = deque([(0, 0)]) # (current airport index, number of flights)
visited = set()
visited.add(0)
while queue:
current, flights = queue.popleft()
if current == n - 1:
return flights
for neighbor in [current - 1, current + 1]:
if 0 <= neighbor < n and neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, flights + 1))
for same_airline in airline_map[airports[current]]:
if same_airline != current and same_airline not in visited:
visited.add(same_airline)
queue.append((same_airline, flights + 1))
airline_map[airports[current]] = []
return -1
关键步骤注释
初始化 BFS:
queue = deque([(0, 0)])
visited = set()
visited.add(0)
探索相邻机场:
for neighbor in [current - 1, current + 1]:
if 0 <= neighbor < n and neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, flights + 1))
探索同航空公司管理的机场:
for same_airline in airline_map[airports[current]]:
if same_airline != current and same_airline not in visited:
visited.add(same_airline)
queue.append((same_airline, flights + 1))
清除已访问的机场列表: airline_map[airports[current]] = []
运行检查