Skip to content

Commit 1e84ce8

Browse files
committed
增加带备忘录的深度优先搜索和动态规划
1 parent 475756a commit 1e84ce8

File tree

6 files changed

+121
-35
lines changed

6 files changed

+121
-35
lines changed

docs/0787-cheapest-flights-within-k-stops.adoc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ https://leetcode.cn/problems/cheapest-flights-within-k-stops/[LeetCode - 787. K
77

88
现在给定所有的城市和航班,以及出发城市 `src` 和目的地 `dst`,你的任务是找到出一条最多经过 `k` 站中转的路线,使得从 `src``dst`*价格最便宜* ,并返回该价格。 如果不存在这样的路线,则输出 `-1`
99

10-
1110
*示例 1:*
1211

1312
image::images/0787-01.png[{image_attr}]
@@ -61,11 +60,10 @@ image::images/0787-03.png[{image_attr}]
6160
6261
== 思路分析
6362

64-
6563
[[src-0787]]
6664
[tabs]
6765
====
68-
一刷(回溯,超时)::
66+
一刷(深度优先搜索,超时)::
6967
+
7068
--
7169
[{java_src_attr}]
@@ -74,12 +72,21 @@ include::{sourcedir}/_0787_CheapestFlightsWithinKStops.java[tag=answer]
7472
----
7573
--
7674
75+
一刷(带备忘录的深度优先搜索)::
76+
+
77+
--
78+
[{java_src_attr}]
79+
----
80+
include::{sourcedir}/_0787_CheapestFlightsWithinKStops_10.java[tag=answer]
81+
----
82+
--
83+
7784
一刷(动态规划)::
7885
+
7986
--
8087
[{java_src_attr}]
8188
----
82-
include::{sourcedir}/_0787_CheapestFlightsWithinKStops_1.java[tag=answer]
89+
include::{sourcedir}/_0787_CheapestFlightsWithinKStops_11.java[tag=answer]
8390
----
8491
--
8592
@@ -93,7 +100,9 @@ include::{sourcedir}/_0787_CheapestFlightsWithinKStops_1.java[tag=answer]
93100
// --
94101
====
95102

96-
97103
== 参考资料
98104

99-
105+
. https://leetcode.cn/problems/cheapest-flights-within-k-stops/solutions/954402/k-zhan-zhong-zhuan-nei-zui-bian-yi-de-ha-abzi/[787. K 站中转内最便宜的航班 - 官方题解^]
106+
. https://leetcode.cn/problems/cheapest-flights-within-k-stops/solutions/955290/gong-shui-san-xie-xiang-jie-bellman-ford-dc94/[787. K 站中转内最便宜的航班 - 运用 Bellman Ford 求解有限制的最短路问题^]
107+
. https://leetcode.cn/problems/cheapest-flights-within-k-stops/solutions/3637197/xi-you-yuan-su-787-k-zhan-zhong-zhuan-ne-xik1/[787. K 站中转内最便宜的航班 - 「稀有猿诉」787. K 站中转内最便宜的航班「DFS/记忆化搜索」^]
108+
. https://leetcode.cn/problems/cheapest-flights-within-k-stops/solutions/956113/tong-ge-lai-shua-ti-la-yi-ti-si-jie-bfs-deqpt/[787. K 站中转内最便宜的航班 - 【彤哥来刷题啦】一题六解:1ms & 100% & 记忆化搜索 & DP & DP优化 & BFS & Bellman-Ford & SPFA!^]

logbook/202503.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ endif::[]
616616
|{counter:codes2503}
617617
|{leetcode_base_url}/cheapest-flights-within-k-stops/[787. K 站中转内最便宜的航班^]
618618
|{doc_base_url}/0787-cheapest-flights-within-k-stops.adoc[题解]
619-
|⭕️ 回溯解法通过 48 / 56 个测试用例。
619+
|⭕️ 深度优先搜索通过 48 / 56 个测试用例。使用带备忘录的深度优先搜索顺利通过。带备忘录的深度优先搜索,也可以优化成动态规划
620620

621621

622622
|===

src/main/java/com/diguage/algo/leetcode/_0787_CheapestFlightsWithinKStops.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
public class _0787_CheapestFlightsWithinKStops {
66
// tag::answer[]
77
/**
8+
* 通过 48 / 56 个测试用例。然后超时
9+
*
810
* @author D瓜哥 · https://www.diguage.com
911
* @since 2025-05-06 18:53:25
1012
*/
@@ -16,13 +18,12 @@ public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
1618
int start = flight[0];
1719
srcMap.computeIfAbsent(start, x -> new ArrayList<>()).add(flight);
1820
}
19-
backtrack(n, srcMap, src, dst, k + 1, 0);
21+
dfs(n, srcMap, src, dst, k + 1, 0);
2022
return result == Integer.MAX_VALUE ? -1 : result;
2123
}
2224

23-
private void backtrack(int n, Map<Integer, List<int[]>> srcMap,
24-
int src, int dst, int k, int expend) {
25-
25+
private void dfs(int n, Map<Integer, List<int[]>> srcMap,
26+
int src, int dst, int k, int expend) {
2627
if (k < 0) {
2728
return;
2829
}
@@ -37,9 +38,10 @@ private void backtrack(int n, Map<Integer, List<int[]>> srcMap,
3738
if (cost + expend >= result) {
3839
continue;
3940
}
40-
backtrack(n, srcMap, idst, dst, k - 1, cost + expend);
41+
dfs(n, srcMap, idst, dst, k - 1, cost + expend);
4142
}
4243
}
44+
4345
// end::answer[]
4446
public static void main(String[] args) {
4547
new _0787_CheapestFlightsWithinKStops().findCheapestPrice(4,

src/main/java/com/diguage/algo/leetcode/_0787_CheapestFlightsWithinKStops_1.java

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.*;
4+
5+
public class _0787_CheapestFlightsWithinKStops_10 {
6+
// tag::answer[]
7+
8+
/**
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-05-06 21:30:38
11+
*/
12+
final int MAX = 100 * 10000 + 1;
13+
14+
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
15+
Map<Integer, List<int[]>> srcMap = new HashMap<>();
16+
for (int[] flight : flights) {
17+
int start = flight[0];
18+
srcMap.computeIfAbsent(start, x -> new ArrayList<>()).add(flight);
19+
}
20+
int[][] memo = new int[n][k + 1];
21+
int result = dfs(n, srcMap, src, dst, k + 1, memo);
22+
return result == MAX ? -1 : result;
23+
}
24+
25+
private int dfs(int n, Map<Integer, List<int[]>> srcMap,
26+
int src, int dst, int k, int[][] memo) {
27+
if (k < 0) {
28+
return MAX;
29+
}
30+
if (src == dst) {
31+
return 0;
32+
}
33+
if (memo[src][k] != 0) {
34+
return memo[src][k];
35+
}
36+
int result = MAX;
37+
for (int[] flight : srcMap.getOrDefault(src, Collections.emptyList())) {
38+
int idst = flight[1];
39+
int cost = flight[2];
40+
result = Math.min(result, dfs(n, srcMap, idst, dst, k - 1, memo) + cost);
41+
}
42+
memo[src][k] = result;
43+
return result;
44+
}
45+
// end::answer[]
46+
public static void main(String[] args) {
47+
new _0787_CheapestFlightsWithinKStops_10().findCheapestPrice(4,
48+
new int[][]{
49+
{0, 1, 100},
50+
{1, 2, 100},
51+
{2, 0, 100},
52+
{1, 3, 600},
53+
{2, 3, 200}}, 0, 3, 1);
54+
}
55+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.diguage.algo.leetcode;
2+
3+
import java.util.Arrays;
4+
5+
public class _0787_CheapestFlightsWithinKStops_11 {
6+
// tag::answer[]
7+
8+
/**
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-05-06 21:40:38
11+
*/
12+
public int findCheapestPrice(int n, int[][] flights, int src, int dst, int k) {
13+
final int MAX = 100 * 10000 + 1;
14+
int[][] dp = new int[k + 2][n];
15+
for (int i = 0; i < k + 2; i++) {
16+
Arrays.fill(dp[i], MAX);
17+
}
18+
dp[0][src] = 0;
19+
for (int i = 1; i < k + 2; i++) {
20+
for (int[] flight : flights) {
21+
int start = flight[0];
22+
int end = flight[1];
23+
int cost = flight[2];
24+
dp[i][end] = Math.min(dp[i][end], dp[i - 1][start] + cost);
25+
}
26+
}
27+
int result = MAX;
28+
for (int i = 1; i < k + 2; i++) {
29+
result = Math.min(result, dp[i][dst]);
30+
}
31+
return result == MAX ? -1 : result;
32+
}
33+
// end::answer[]
34+
public static void main(String[] args) {
35+
new _0787_CheapestFlightsWithinKStops_11().findCheapestPrice(4,
36+
new int[][]{
37+
{0, 1, 100},
38+
{1, 2, 100},
39+
{2, 0, 100},
40+
{1, 3, 600},
41+
{2, 3, 200}}, 0, 3, 1);
42+
}
43+
}

0 commit comments

Comments
 (0)