Skip to content

java-leetcode-classroom/java_cheapest_flights_within_k

Repository files navigation

java_cheapest_flights_within_k

There are n cities connected by some number of flights. You are given an array flights where flights[i] = [fromi, toi, pricei] indicates that there is a flight from city fromi to city toi with cost pricei.

You are also given three integers srcdst, and k, return the cheapest price from src to dst with at most k stops. If there is no such route, return **-1.

Examples

Example 1:

https://assets.leetcode.com/uploads/2022/03/18/cheapest-flights-within-k-stops-3drawio.png

Input: n = 4, flights = [[0,1,100],[1,2,100],[2,0,100],[1,3,600],[2,3,200]], src = 0, dst = 3, k = 1 Output: 700 Explanation: The graph is shown above. The optimal path with at most 1 stop from city 0 to 3 is marked in red and has cost 100 + 600 = 700. Note that the path through cities [0,1,2,3] is cheaper but is invalid because it uses 2 stops. 

Example 2:

https://assets.leetcode.com/uploads/2022/03/18/cheapest-flights-within-k-stops-1drawio.png

Input: n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, k = 1 Output: 200 Explanation: The graph is shown above. The optimal path with at most 1 stop from city 0 to 2 is marked in red and has cost 100 + 100 = 200. 

Example 3:

https://assets.leetcode.com/uploads/2022/03/18/cheapest-flights-within-k-stops-2drawio.png

Input: n = 3, flights = [[0,1,100],[1,2,100],[0,2,500]], src = 0, dst = 2, k = 0 Output: 500 Explanation: The graph is shown above. The optimal path with no stops from city 0 to 2 is marked in red and has cost 500. 

Constraints:

  • 1 <= n <= 100
  • 0 <= flights.length <= (n * (n - 1) / 2)
  • flights[i].length == 3
  • 0 <= fromi, toi < n
  • fromi != toi
  • 1 <= pricei <= 104
  • There will not be any multiple flights between two cities.
  • 0 <= src, dst, k < n
  • src != dst

解析

題目給定一個整數 n 代表有 0 到 n-1 的飛機站

給定一個 flights 矩陣 , 矩陣中每個 entry , flight[i] = [$source_i, target_i, price_i$]

代表從 $source_i$ 出發到 $target_i$ 需要花費 $price_i$

給定一個整數 src 代表出發站

給定一個整數 dst 代表到達站

給定一個整數 k 代表最多只經過 k 個中繼站

要求在以上條件下實作一個演算法找出最便宜的從 src 到 dst 的票價

這題如果要使用 Dijkstra Algorithm

會需要注意有最多 k 中繼站的限制

也就是可能要跑 1 到 k 次 Dijkstra Algorithm 來處理

而這題剛好適合用 Bellman ford Algorithm

可以用每次從 src 出發透過可行的邊去更新 在level L 的限制之下的 prices

這樣只要更新 k+1 次(除了 source 之外有k+1個點)最後 prices[dst] 就是結果

這樣時間複雜度會是 O(E*k)

其中 E 代表邊的個數, k 是 level

程式碼

import java.util.Arrays; public class Solution { public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) { int[] prices = new int[n]; Arrays.fill(prices, Integer.MAX_VALUE); prices[src] = 0; for (int level = 1; level <= k+1; level++) { int[] levelPrices = Arrays.copyOf(prices, n); for (int[] flight: flights) { int source = flight[0]; int target = flight[1]; int price = flight[2]; if (prices[source] == Integer.MAX_VALUE) { continue; } if (levelPrices[target] > prices[source] + price) { levelPrices[target] = prices[source] + price; } } // copy current prices to prices prices = Arrays.copyOf(levelPrices, n); } if (prices[dst] == Integer.MAX_VALUE) { return -1; } return prices[dst]; } }

困難點

  1. 比一般的 shortest path 多了一個 最多 k 個中繼站的限制
  2. 理解如何逐步更新每個 level 的 prices

Solve Point

  • 需要理解Bellman ford Algorithm
  • 建立一個 prices 陣列來儲存當下 level 的 prices 更新結果
  • 每次更新都需要用上一個 level 的更新結果來當做基準