「力扣」第 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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章