We have a list of bus routes. Each routes[i] is a bus route that the i-th bus repeats forever. For example if routes[0] = [1, 5, 7], this means that the first bus (0-th indexed) travels in the sequence 1->5->7->1->5->7->1->… forever.
We start at bus stop S (initially not on a bus), and we want to go to bus stop T. Travelling by buses only, what is the least number of buses we must take to reach our destination? Return -1 if it is not possible.
Example:
Input:
routes = [[1, 2, 7], [3, 6, 7]]
S = 1
T = 6
Output: 2
Explanation:
The best strategy is take the first bus to the bus stop 7, then take the second bus to the bus stop 6.
Note:
1 <= routes.length <= 500.
1 <= routes[i].length <= 500.
0 <= routes[i][j] < 10 ^ 6.
BFS求解,程序如下所示:
class Solution {
public int numBusesToDestination(int[][] routes, int S, int T) {
if (S == T){
return 0;
}
List<List<Integer>> list = new ArrayList<>();
for (int i = 0; i < routes.length; ++ i){
Arrays.sort(routes[i]);
list.add(new ArrayList<Integer>());
}
for (int i = 0; i < routes.length; ++ i){
for (int j = i + 1; j < routes.length; ++ j){
if (intersection(routes[i], routes[j])){
list.get(i).add(j);
list.get(j).add(i);
}
}
}
Set<Integer> begin = new HashSet<>();
Set<Integer> target = new HashSet<>();
Queue<Integer> que = new ArrayDeque<>();
Queue<Integer> depth = new ArrayDeque<>();
for (int i = 0; i < routes.length; ++ i){
if (Arrays.binarySearch(routes[i], S) >= 0){
begin.add(i);
que.offer(i);
depth.offer(0);
}
if (Arrays.binarySearch(routes[i], T) >= 0){
target.add(i);
}
}
while (!que.isEmpty()){
int size = que.size();
for (int i = 0; i < size; ++ i){
int node = que.poll();
int dep = depth.poll();
if (target.contains(node)){
return dep + 1;
}
for (Integer neighbor : list.get(node)){
if (!begin.contains(neighbor)){
begin.add(neighbor);
que.offer(neighbor);
depth.offer(dep + 1);
}
}
}
}
return -1;
}
public boolean intersection(int[] A, int[] B){
int i = 0, j = 0;
while (i < A.length && j < B.length){
if (A[i] == B[j]){
return true;
}
else if (A[i] < B[j]){
i ++;
}
else {
j ++;
}
}
return false;
}
}