Give anundirected graph, in which each edge's length is1, and givetwonodes from the graph. We need to find thelengthofthe shortest pathbetween the giventwonodes.
Example
Given graph ={1,2,4#2,1,4#3,5#4,1,2#5,3}, and nodeA =3, nodeB =5.
1------2 3
\ | |
\ | |
\ | |
\ | |
4 5
return1
Code
public class Solution {
/**
* @param graph: a list of Undirected graph node
* @param A: nodeA
* @param B: nodeB
* @return: the length of the shortest path
*/
public int shortestPath(List<UndirectedGraphNode> graph, UndirectedGraphNode A, UndirectedGraphNode B) {
// Write your code here
Queue<UndirectedGraphNode> queue = new LinkedList<>();
Set<UndirectedGraphNode> set = new HashSet<>();
queue.offer(A);
set.add(A);
int result = 0;
while (!queue.isEmpty()) {
int size = queue.size();
result++;
for (int i = 0; i < size; i++) {
UndirectedGraphNode current = queue.poll();
for (UndirectedGraphNode n : current.neighbors) {
if (set.contains(n)) {
continue;
}
if (n.label == B.label) {
return result;
}
queue.offer(n);
set.add(n);
}
}
}
return -1;
}
}
Q.双向BFS是否真的能提高效率?
假设单向BFS需要搜索 N 层才能到达终点,每层的判断量为 X,那么总的运算量为X ^ N. 如果换成是双向BFS,前后各自需要搜索 N / 2 层,总运算量为2 * X ^ {N / 2}。如果 N 比较大且X 不为 1,则运算量相较于单向BFS可以大大减少,差不多可以减少到原来规模的根号的量级。
/**
* Definition for graph node.
* class UndirectedGraphNode {
* int label;
* ArrayList<UndirectedGraphNode> neighbors;
* UndirectedGraphNode(int x) {
* label = x; neighbors = new ArrayList<UndirectedGraphNode>();
* }
* };
*/
public int doubleBFS(UndirectedGraphNode start, UndirectedGraphNode end) {
if (start.equals(end)) {
return 1;
}
// 起点开始的BFS队列
Queue<UndirectedGraphNode> startQueue = new LinkedList<>();
// 终点开始的BFS队列
Queue<UndirectedGraphNode> endQueue = new LinkedList<>();
startQueue.add(start);
endQueue.add(end);
int step = 0;
// 记录从起点开始访问到的节点
Set<UndirectedGraphNode> startVisited = new HashSet<>();
// 记录从终点开始访问到的节点
Set<UndirectedGraphNode> endVisited = new HashSet<>();
startVisited.add(start);
endVisited.add(end);
while (!startQueue.isEmpty() || !endQueue.isEmpty()) {
int startSize = startQueue.size();
int endSize = endQueue.size();
// 按层遍历
step ++;
for (int i = 0; i < startSize; i ++) {
UndirectedGraphNode cur = startQueue.poll();
for (UndirectedGraphNode neighbor : cur.neighbors) {
if (startVisited.contains(neighbor)) {//重复节点
continue;
} else if (endVisited.contains(neighbor)) {//相交
return step;
} else {
startVisited.add(neighbor);
startQueue.add(neighbor);
}
}
}
step ++;
for (int i = 0; i < endSize; i ++) {
UndirectedGraphNode cur = endQueue.poll();
for (UndirectedGraphNode neighbor : cur.neighbors) {
if (endVisited.contains(neighbor)) {
continue;
} else if (startVisited.contains(neighbor)) {
return step;
} else {
endVisited.add(neighbor);
endQueue.add(neighbor);
}
}
}
}
return -1; // 不连通
}