61 阿D的最佳飞行路线探索 | 豆包MarsCode AI刷题

35 阅读3分钟

题目描述:

阿D驾驶一架飞机需要从出发点抵达目的地,但是由于特殊的航空管制,对飞机的飞行路线有严格要求:飞机只能飞向当前机场的前后相邻机场或者相同航空公司管理的机场。现在阿D的leader要求阿D设计最佳的飞行路线,使得起飞次数最少。为此,阿D将所有的机场用一个数组arr表示,其中:

  • 数组中每个元素表示不同的机场,元素的值表示不同的航空公司。
  • arr[0]表示出发点,arr[arr.length - 1]表示目的地。
  • 假设当前在机场i(数组下标为i),则i - 1i - 1 >= 0)和i + 1i + 1 < arr.length)表示当前机场的前后机场,则飞机可以飞向编号为i - 1i + 1的机场。
  • 假设当前在机场i,且数组中存在arr[i] == arr[j],则表示机场i和机场j为相同航空公司管理,则飞机可以飞向编号为j的机场。

测试样例:

  • 输入:arr = [10,12,13,12,14]

    • 输出:3
    • 说明:最佳飞行路线:机场编号 0(出发点) -> 机场编号 1 -> 机场编号 3 -> 机场编号 4(目的地)
  • 输入:arr = [10,11,12,13,14]

    • 输出:4
    • 说明:最佳飞行路线:机场编号 0(出发点) -> 机场编号 1 -> 机场编号 2 -> 机场编号 3 -> 机场编号 4(目的地)

解题思路:

  1. 理解问题:我们需要找到从起点到终点的最少起飞次数。飞机可以从当前机场飞到相邻机场,或者飞到相同航空公司的其他机场。

  2. 数据结构选择

    • 使用队列(std::queue)来进行广度优先搜索(BFS)。
    • 使用集合(std::unordered_set)来记录已经访问过的机场,避免重复访问。
  3. 算法步骤

    • 初始化队列,将起点加入队列。
    • 初始化集合,记录已经访问过的机场。
    • 每次从队列中取出一个机场,检查其相邻机场和相同航空公司的机场。
    • 如果找到终点,返回当前的起飞次数。
    • 如果没有找到终点,将未访问过的机场加入队列,并标记为已访问。

代码实现

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_set>

int solution(std::vector<int> airports) {
    int n = airports.size();
    std::queue<int> q;
    std::unordered_set<int> visited;
    
    // 初始化队列,将起点加入队列
    q.push(0);
    visited.insert(0);
    
    int steps = 0;
    
    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.find(current - 1) == visited.end()) {
                q.push(current - 1);
                visited.insert(current - 1);
            }
            if (current + 1 < n && visited.find(current + 1) == visited.end()) {
                q.push(current + 1);
                visited.insert(current + 1);
            }
            
            // 检查相同航空公司的机场
            for (int j = 0; j < n; ++j) {
                if (airports[j] == airports[current] && visited.find(j) == visited.end()) {
                    q.push(j);
                    visited.insert(j);
                }
            }
        }
        steps++;
    }
    
    return -1; // 如果无法到达终点,返回-1
}

int main() {
    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;
}

总结:

  • 本题通过广度优先搜索(BFS)来找到从起点到终点的最短路径。
  • 使用队列来实现 BFS,确保我们找到的是最短路径。
  • 使用集合来记录已经访问过的机场,避免重复访问。
  • 通过逐步扩展搜索,最终找到最少起飞次数