leetcode每日一题系列-公交路线 leetcode-8

leetcode-815-公交路线

这是我参与更文挑战的第6天,活动详情查看: 更文挑战

[博客链接]

菜🐔的学习之路

掘金首页

[题目描述]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
css复制代码给你一个数组 routes ,表示一系列公交线路,其中每个 routes[i] 表示一条公交线路,第 i 辆公交车将会在上面循环行驶。 


例如,路线 routes[0] = [1, 5, 7] 表示第 0 辆公交车会一直按序列 1 -> 5 -> 7 -> 1 -> 5 -> 7 -> 1
-> ... 这样的车站路线行驶。


现在从 source 车站出发(初始时不在公交车上),要前往 target 车站。 期间仅可乘坐公交车。

求出 最少乘坐的公交车数量 。如果不可能到达终点车站,返回 -1 。



示例 1:


输入:routes = [[1,2,7],[3,6,7]], source = 1, target = 6
输出:2
解释:最优策略是先乘坐第一辆公交车到达车站 7 , 然后换乘第二辆公交车到车站 6 。


示例 2:


输入:routes = [[7,12],[4,5,15],[6],[15,19],[9,12,13]], source = 15, target = 12
输出:-1




提示:


1 <= routes.length <= 500.
1 <= routes[i].length <= 105
routes[i] 中的所有值 互不相同
sum(routes[i].length) <= 105
0 <= routes[i][j] < 106
0 <= source, target < 106

Related Topics 广度优先搜索 数组 哈希表
👍 146 👎 0

[题目链接]

leetcode题目链接

[github地址]

代码链接

[思路介绍]

思路一:BFS

  • 分析题意可以很快的想到DFS或者BFS解决,因为本题只需要考虑选择的公交车线路数量,不需要考虑站点路线,所以用广度优先即可,最先遍历到的一定是最短的
  • 考虑题解的时候有如下问题:
    • 因为最开始不在公交车上且在1站台,需要考虑是否routes[0]包含1站台,当然这只是一个前提条件并不影响后续的解题过程,不失一般性的我们假设第一条线路一定包含起始站台
  • 首先确认链路关系,将所有线路和线路中的包含的站台存入map,key为线路索引,value为站台组成的set
  • 然后依次遍历所有map,当有线路包含source站台的时候存入deque作为BFS遍历的跟节点
  • 定义另一个map存入转移到当前线路的step,key为当前线路索引,value为step
  • 接下来就是常规的BFS解析了
  • 需要注意的是本题有两个边界情况
    • 起始和终点在一条线路上,直接返回0,虽然我觉得这个边界和题目描述的初始不在公交车上有冲突
    • 所有线路没有起点站台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
java复制代码public int numBusesToDestination(int[][] routes, int source, int target) {

//确立所有线路的包含关系
Map<Integer, Set<Integer>> map = new HashMap<>();
for (int i = 0; i < routes.length; i++) {
Set<Integer> set = new HashSet<>();
for (int j = 0; j < routes[i].length; j++) {
set.add(routes[i][j]);
}
map.put(i, set);
}

//存储线路索引
Deque<Integer> deque = new LinkedList<>();
//记录到当前站点的线路数量
Map<Integer, Integer> res = new HashMap<>();
//确立初始站台
for (Integer i : map.keySet()) {
if (map.get(i).contains(source)) {
deque.add(i);
res.put(i, 1);
}
}
//corner case
if (deque.isEmpty()){
return -1;
}
if (target==source){
return 0;
}
while (!deque.isEmpty()) {
int temp = deque.poll();
int step = res.get(temp);
for (int i : map.get(temp)) {
if (i == target) {
return step;
}
for (int line : map.keySet()) {
//包含当前节点的线路全部加入到deque中继续广度优先遍历
if (res.containsKey(line)) {
continue;
}
if (map.get(line).contains(i)) {
deque.add(line);
res.put(line, step + 1);
}
}

}
}
return -1;

}

时间复杂度O(∑0nroutes+n2\sum_{0}^{n}routes+n^2∑0n​routes+n2)

n为线路数,求和公式为每条线路上站台的数量和

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%