「力扣」第 787 题:K 站中转内最便宜的航班(深度优先遍历、广度优先遍历)

方法一:深度优先遍历(回溯算法)

说明:

  • 航班没有重复,且不存在环路;
  • 每个航班的价格范围是 [1, 10000]

Java 代码:

public class Solution {

    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
        // 构建邻接矩阵
        int[][] graph = new int[n][n];
        for (int[] flight : flights) {
            graph[flight[0]][flight[1]] = flight[2];
        }

        int[] res = new int[1];
        res[0] = Integer.MAX_VALUE;
        boolean[] visited = new boolean[n];
        // 注意:这里传 K + 1,K 次经停,总共 K + 1 个站
        dfs(graph, src, dst, K + 1, 0, visited, res);

        if (res[0] == Integer.MAX_VALUE) {
            return -1;
        }
        return res[0];
    }

    private void dfs(int[][] graph, int src, int dst, int k, int cost, boolean[] visited, int[] res) {
        if (src == dst) {
            res[0] = cost;
            return;
        }

        if (k == 0) {
            return;
        }

        int n = graph[src].length;
        for (int i = 0; i < n; i++) {
            // 注意 1:这里 graph[src][i] > 0
            if (graph[src][i] > 0) {
                if (visited[i]) {
                    continue;
                }

                if (cost + graph[src][i] > res[0]) {
                    continue;
                }

                // 搜索
                visited[i] = true;
                dfs(graph, i, dst, k - 1, cost + graph[src][i], visited, res);
                visited[i] = false;
            }
        }
    }
}

方法二:广度优先遍历

Java 代码:

import java.util.LinkedList;
import java.util.Queue;

public class Solution {

    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int K) {
        // 构建邻接矩阵
        int[][] graph = new int[n][n];
        for (int[] flight : flights) {
            graph[flight[0]][flight[1]] = flight[2];
        }

        int res = Integer.MAX_VALUE;
        Queue<int[]> queue = new LinkedList<>();
        // [src, 到 src 的花费]
        queue.offer(new int[]{src, 0});
        int k = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] head = queue.poll();
                int currentPrice = head[1];

                for (int j = 0; j < n; j++) {
                    // 注意:这里 graph[head[0]][j] > 0
                    if (graph[head[0]][j] > 0) {
                        if (j == dst) {
                            res = Math.min(res, currentPrice + graph[head[0]][dst]);
                            // 注意:这里不能直接返回,因为有松弛操作
                        }
                        if (currentPrice + graph[head[0]][j] < res) {
                            queue.offer(new int[]{j, currentPrice + graph[head[0]][j]});
                        }
                    }
                }
            }

            if (k == K){
                break;
            }
            k++;
        }

        if (res == Integer.MAX_VALUE){
            return -1;
        }
        return res;
    }
}

你可能感兴趣的:(力扣)