问题描述
阿D驾驶一架飞机需要从出发点抵达目的地,但是由于特殊的航空管制,对飞机的飞行路线有严格要求:飞机只能飞向当前机场的前后相邻机场或者相同航空公司管理的机场。现在阿D的leader要求阿D设计最佳的飞行路线,使得起飞次数最少。为此,阿D将所有的机场用一个数组arr
表示,其中:
- 数组中每个元素表示不同的机场,元素的值表示不同的航空公司。
arr[0]
表示出发点,arr[arr.length - 1]
表示目的地。- 假设当前在机场
i
(数组下标为i
),则i - 1
(i - 1 >= 0
)和i + 1
(i + 1 < arr.length
)表示当前机场的前后机场,则飞机可以飞向编号为i - 1
和i + 1
的机场。 - 假设当前在机场
i
,且数组中存在arr[i] == arr[j]
,则表示机场i
和机场j
为相同航空公司管理,则飞机可以飞向编号为j
的机场。
输入格式
用数组表示所有机场
数据范围:
1 <= arr.length <= 5 * 10^4
-10^8 <= arr[i] <= 10^8
输出格式
最少起飞次数
示例 1:
输入:arr = [10,12,13,12,14]
输出:3
最佳飞行路线:机场编号 0(出发点) -> 机场编号 1 -> 机场编号 3 -> 机场编号 4(目的地)
说明:arr[1]
和arr[3]
等于 12,为相同航空公司管理,机场编号 1 可以直接飞到机场编号 3
示例 2:
输入:arr = [10,11,12,13,14]
输出:4
最佳飞行路线:机场编号 0(出发点) -> 机场编号 1 -> 机场编号 2 -> 机场编号 3 -> 机场编号 4(目的地)
说明:数组中均为不同机场,只能逐一向前飞行
#include <vector>
#include <unordered_map>
#include <queue>
int solution(std::vector<int> airports) {
int n = airports.size();
if (n == 1) return 0; // 只有一个机场,不需要起飞
// 1. 初始化数据结构
std::unordered_map<int, std::vector<int>> airlineMap;
for (int i = 0; i < n; ++i) {
airlineMap[airports[i]].push_back(i);
}
std::queue<int> q;
std::vector<bool> visited(n, false);
// 2. BFS初始化
q.push(0);
visited[0] = true;
int steps = 0;
// 3. BFS遍历
while (!q.empty()) {
int size = q.size();
for (int i = 0; i < size; ++i) {
int current = q.front();
q.pop();
// 检查是否到达目的地
if (current == n - 1) return steps;
// 检查相邻机场
if (current - 1 >= 0 && !visited[current - 1]) {
q.push(current - 1);
visited[current - 1] = true;
}
if (current + 1 < n && !visited[current + 1]) {
q.push(current + 1);
visited[current + 1] = true;
}
// 检查相同航空公司的机场
for (int next : airlineMap[airports[current]]) {
if (!visited[next]) {
q.push(next);
visited[next] = true;
}
}
// 清空当前航空公司的机场列表,避免重复访问
airlineMap[airports[current]].clear();
}
steps++;
}
// 4. 返回结果
return -1; // 如果BFS完成且未找到目的地
}
int main() {
// You can add more test cases here
std::vector<int> airports1 = {10, 12, 13, 12, 14};
std::vector<int> airports2 = {10, 11, 12, 13, 14};
std::cout << (solution(airports1) == 3) << std::endl;
std::cout << (solution(airports2) == 4) << std::endl;
return 0;
}
解题思路:
-
初始化数据结构:
airlineMap
存储每个航空公司的机场列表。q
是BFS的队列,用于存储待访问的机场。visited
用于标记已经访问过的机场。
-
BFS初始化:
- 将起点(
arr[0]
)加入队列,并标记为已访问。
- 将起点(
-
BFS遍历:
- 从队列中取出一个机场,检查其相邻机场(
i-1
和i+1
)和相同航空公司的机场。 - 如果某个机场是目的地,返回当前的起飞次数。
- 如果某个机场未被访问过,将其加入队列,并标记为已访问。
- 从队列中取出一个机场,检查其相邻机场(
-
返回结果:
- 如果BFS完成且未找到目的地,返回
-1
。
- 如果BFS完成且未找到目的地,返回
总结
通过使用BFS,我们可以有效地找到从起点到终点的最少起飞次数。BFS的逐层扩展特性确保了我们找到的是最短路径。