问题描述
小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),或者飞往同一家航空公司管理的其他机场。。 -
数据结构选择:
- 图的表示:我们可以使用邻接表来表示机场之间的连接关系。每个机场可以连接到相邻的机场和同一家航空公司的其他机场。
- BFS(广度优先搜索) :由于我们需要找到最短路径,BFS是一个合适的选择。BFS可以保证在无权图中找到最短路径。
-
算法步骤:
- 构建图: - 遍历每个机场,将其与相邻机场(
i-1和i+1)和同一家航空公司的其他机场连接起来。 - BFS搜索:
- 从起点机场开始,使用BFS遍历图,记录起飞次数。
- 当到达终点机场时,返回当前的起飞次数。
- 构建图: - 遍历每个机场,将其与相邻机场(
代码实现与详解
下面是完整的 Python 实现:
def solution(airports):
n = len(airports)
# 构建图的邻接表
graph = defaultdict(list)
for i in range(n):
# 添加相邻机场的边
if i > 0:
graph[i - 1].append(i)
graph[i].append(i - 1)
if i < n - 1:
graph[i].append(i + 1)
graph[i + 1].append(i)
# 添加相同航空公司机场的边
for j in range(n):
if i != j and airports[i] == airports[j]:
graph[i].append(j)
graph[j].append(i)
# 使用BFS寻找最短路径
queue = deque([(0, 0)]) # (当前机场, 起飞次数)
visited = set([0])
while queue:
current, takeoffs = queue.popleft()
if current == n - 1:
return takeoffs
for neighbor in graph[current]:
if neighbor not in visited:
visited.add(neighbor)
queue.append((neighbor, takeoffs + 1))
# 如果无法到达终点(理论上不会发生,因为所有机场都是连通的),则返回-1或其他错误码
return -1
# 测试用例
if __name__ == "__main__":
print(solution([10, 12, 13, 12, 14]) == 3)
print(solution([10, 11, 12, 13, 14]) == 4)
print(solution([7, 7, 7, 8, 9, 7]) == 1)
代码详解
-
构建图:我们使用一个邻接表来表示图,其中每个节点(机场)都有一个列表,存储与之直接相连的其他节点(机场)。
-
添加边:
- 对于每个机场,我们添加与其相邻机场的边。
- 对于每个机场,我们添加与其属于同一航空公司的其他机场的边。
-
BFS搜索:
- 我们从起点(机场0)开始,使用BFS来搜索到终点的最短路径。
- 我们使用一个队列来存储当前位置和起飞次数。
- 我们使用一个集合来跟踪已经访问过的机场,以避免重复访问。
-
返回结果:当BFS找到终点时,我们返回当前的起飞次数。
知识总结
-
图论基础:
- 图是由节点(在此问题中为机场)和边(连接机场的路线)组成的结构。
- 在此问题中,我们构建了一个无向图,因为飞机可以在两个机场之间双向飞行。
-
广度优先搜索(BFS) :
- BFS是一种遍历或搜索图(或树)的算法,从起始节点开始,首先访问所有相邻节点,然后对每个相邻节点重复此过程。
- BFS特别适用于寻找无权图中的最短路径(即路径上的边具有相同权重)。
工具运用
在刷题的过程中,如果没有思路,可以借助MarsCode AI工具,它不仅能提示思路,还能提示代码(给一个框架),检查代码,优化代码等等。 在读完题目后我无从下手,不知道要用什么算法与数据结构,通过MarsCode AI的提示后就有了明确的方向和思路,就能跟着他的逻辑走下去。 不仅如此,他还帮我总结了用到的知识点(算法:广度优先搜索 与 数据结构:图)能很大程度上提升学习效率,相当于在做题的同时帮我形成笔记。
总而言之,这是一个能提高写代码效率的辅助工具,是程序员的好partner。