题目如下:
我的想法如下:
目标是求解在特定约束下从起点机场到达终点机场所需的最小起飞次数。其核心思想是利用 广度优先搜索(BFS) ,结合机场邻接关系和航空公司连接规则,寻找最短路径。
-
输入与问题建模:
-
输入是一个数组
airports,每个元素表示一个机场所属的航空公司。 -
起点是
airports[0],终点是airports[-1]。 -
约束条件:
- 可以飞往相邻机场(
i-1或i+1)。 - 可以飞往同一航空公司的其他机场。
- 可以飞往相邻机场(
-
-
构建航空公司连接图:
-
使用
defaultdict构建一个字典company_airports,将每个航空公司管理的机场索引存为列表。例如,airports = [10, 12, 13, 12, 14]会生成:python
复制
{ 10: [0], 12: [1, 3], 13: [2], 14: [4] }
-
-
广度优先搜索(BFS) :
-
使用队列
queue存储(当前机场索引, 已飞行次数)。 -
使用集合
visited存储已访问的机场,避免重复访问。 -
每次从队列中取出当前机场:
- 如果当前机场是终点,返回飞行次数。
- 否则,将所有可能的下一步机场(包括相邻机场和同一航空公司的机场)加入队列,并标记为已访问。
-
BFS 保证了第一次到达终点时的路径是最优(即最少飞行次数)。
-
-
终止条件:
- 如果到达终点,返回飞行次数。
- 如果队列为空且未到达终点,返回
-1(题目保证有解,所以此情况不会发生)。
个人思考
-
关于问题建模:
- 本题实际上是一个 图论问题,机场为节点,航线为边。相邻机场和同一航空公司机场共同构成了节点之间的连接关系。
- BFS 是解决最短路径问题的优选方法,尤其适用于无权图。
-
代码的高效性:
- BFS 的时间复杂度为
O(V + E),其中V是节点数,E是边数。 - 在本题中,
V = n(机场个数),E包括相邻机场的连接数(O(n))和航空公司连接数(最坏情况下O(n^2),因为一个航空公司可能包含所有机场)。 - 空间复杂度主要由队列和访问集合
visited决定,均为O(n)。
- BFS 的时间复杂度为
-
优化潜力:
-
如果某航空公司连接的机场数量较多,可能会导致冗余访问。因此,在处理同一航空公司机场时,可以先清空其连接列表,避免重复加入队列:
python
复制
next_airports.update(company_airports.pop(curr_company, []))
-
-
通用性:
- 这种 BFS 解法可扩展到其他类似问题,例如带有特殊跳跃规则的路径问题、迷宫最短路径问题等。
- 核心在于根据题目特点,合理设计节点的邻接关系。
这类题型的解题思路
-
理解题意,抽象问题:
- 识别问题的本质是否是路径最短、连通性等图论问题。
- 确定节点(机场)和边(相邻机场或同航空公司机场)之间的关系。
-
选择合适的算法:
- 最短路径问题一般适用 BFS(无权图)或 Dijkstra(有权图)。
- 如果目标是判断连通性,可考虑 DFS 或并查集。
-
构建图的表示:
- 使用邻接表、邻接矩阵或其他数据结构表示图。
- 根据题目规则动态生成图的邻接关系。
-
实现搜索过程:
- 如果是最短路径,优先使用 BFS。
- 使用队列存储状态,结合访问标记避免冗余处理。
-
考虑边界情况:
- 输入为空或只有一个机场时,直接返回 0。
- 确保所有节点都能访问到终点,必要时检查连通性。
-
优化与验证:
- 优化时间复杂度,避免不必要的重复计算。
- 使用多组测试用例验证程序正确性和鲁棒性。
总结示例
以本题为例,解题步骤如下:
-
理解问题:
- 每个机场是一个节点,存在两类边:相邻机场边和同航空公司边。
- 要求起点到终点的最短路径,即最少起飞次数。
-
选择 BFS:
- BFS 遍历所有可能的路径,找到最先到达终点的那条。
-
构建图:
- 用字典存储航空公司连接关系,简化同公司机场的查找。
- 动态生成邻接节点集合。
-
实现 BFS:
- 队列存储当前状态,逐层扩展。
- 访问过的节点标记为已访问,避免重复处理。
-
返回结果:
- 到达终点时,直接返回当前的飞行次数。 附代码: