0
点赞
收藏
分享

微信扫一扫

K 站中转内最便宜的航班

村里搬砖的月野兔 2021-09-21 阅读 69
今日算法
题目描述:
示例 1:
示例 2:
题目分析:
  1. 最多经过k站到达目的地,也就是中转次数num <= k;
  2. 从 src 到 dst 的 价格最便宜,也就是从src每次中转达到dst的价格之和,最后要最小。
思路:

使用深度遍历递归,当k == 0时且当前城市不等于目的地城市,或者当前价格之后大于最小价格和时,作为递归出口。如果k >= 0且当前城市等于目的地城市,则判断当前价格是否小于最小价格,是则替换。(超时)

代码实现:
class Solution {
    public Map<Integer, ArrayList<Integer>> map = new HashMap();
    public int[][] prices;
    public int maxNum = -1;
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
       int row = flights.length;
        prices = new int[n][n];
        for (int i = 0; i < n; i++) {
            ArrayList<Integer> list = map.getOrDefault(i, new ArrayList<Integer>());
            for (int j = 0; j < row; j++) {
                if (i == flights[j][0]) {
                    list.add(flights[j][1]);
                    prices[flights[j][0]][flights[j][1]] = flights[j][2];
                }
            }
            map.put(i, list);
        }
        dfs(k + 1, src, dst, 0);

        return maxNum;
    }

    public void dfs(int k, int src, int dst, int price) {
        if (k == 0 && src != dst) return; // k == 0且当前城市不是目的地,返回。
        if (maxNum != -1 && price >= maxNum) return; // 当前价格大于最小价格,返回。
        if (k >= 0 && src == dst) { // k >= 0且当前城市是目的地城市
            if (maxNum == -1 || maxNum > price) maxNum = price; // 计算最小价格
            return;
        }
        ArrayList<Integer> list = map.get(src); // 获取当前城市可以到达的中转城市
        if (list == null) return; // 不存在则返回
        for (Integer num : list) {
            int total = prices[src][num];
            dfs(k - 1, num, dst, price + total); // 前往下一个城市
        }
    }
}
思路:
class Solution {
    public int INF = 1000007;
    public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
        return bfs(n, flights, src, dst, k);
    }
    public int bfs(int n, int[][] flights, int src, int dst, int k) {
        List<int[]>[] arr = new List[n]; // 索引i代表当前城市,arr[i]代表当前城市可以到达的城市以及花费
        for (int i = 0; i < n; i++) {
            arr[i] = new ArrayList();
        }
        for (int[] flight : flights) {
            arr[flight[0]].add(new int[]{flight[1], flight[2]});
        }
        int[] ans = new int[n]; // 从src到达索引i城市的最小花费
        Arrays.fill(ans, INF);
        Queue<int[]> queue = new LinkedList();
        queue.offer(new int[]{src, 0});
        while (!queue.isEmpty() && k + 1 > 0) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {
                int[] poll = queue.poll();
                for (int[] path : arr[poll[0]]) {
                    int distance = poll[1] + path[1];
                    if (distance < ans[path[0]] && distance < ans[dst]) {
                        ans[path[0]] = distance;
                        if (path[0] != dst) { // 不是终点,继续添加。
                            queue.offer(new int[]{path[0], distance});
                        }
                    }
                }
            }
            k--;
        }
        return ans[dst] >= INF ? -1 : ans[dst];
    }
}
举报

相关推荐

0 条评论