题目描述:
示例 1:
示例 2:
题目分析:
- 最多经过k站到达目的地,也就是中转次数num <= k;
- 从 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];
}
}