BFS模板 + 力扣例题
DFS和BFS的区别:
BFS的时间复杂度是O(logn),DFS的时间复杂度是O(n)。BFS更节省时间,速度更快。
BFS模板:
1 int BFS(Node start, Node target)//计算从起点start到终点target的距离 2 { 3 Queue<Node> q;//核心数据结构,队列 4 Set<Node> visited;//访问过的不再访问,避免走回头路 5 // 但是在二叉树结构里面不存在子节点访问父节点,所以不需要visited集合 6 7 q.offer(start);//把起点加入队列 8 visited.add(start); 9 int step = 0;//step表示遍历的层数,也是步数 10 11 while(q not empty()) 12 { 13 int n = q.size(); 14 /*将目前队列里所有的结点往邻接结点遍历*/ 15 for(int i=0;i<n;i++) 16 { 17 Node curr = q.poll(); 18 /*判断是否到达终点,也就是是否到达目标点*/ 19 if(cur is target) 20 { 21 return step; 22 } 23 /*将cur的邻近结点加入到队列里面*/ 24 for(Node x : cur.adj()){ 25 if(x not in visited) 26 { 27 q.offer(x); 28 visited.add(x); 29 } 30 } 31 } 32 //更新步数,也就是更新遍历的层数 33 step++; 34 } 35 }
双向 BFS:
双向 BFS还是遵循 BFS 算法框架的,只是不再使用队列,而是使用 HashSet 方便快速判断两个集合是否有交集。
1 int openLock(String[] deadends, String target) { 2 Set<String> deads = new HashSet<>(); 3 for (String s : deadends) deads.add(s); 4 // 用集合不用队列,可以快速判断元素是否存在 5 Set<String> q1 = new HashSet<>(); 6 Set<String> q2 = new HashSet<>(); 7 Set<String> visited = new HashSet<>(); 8 9 int step = 0; 10 q1.add("0000"); 11 q2.add(target); 12 13 while (!q1.isEmpty() && !q2.isEmpty()) { 14 // 哈希集合在遍历的过程中不能修改,用 temp 存储扩散结果 15 Set<String> temp = new HashSet<>(); 16 17 /* 将 q1 中的所有节点向周围扩散 */ 18 for (String cur : q1) { 19 /* 判断是否到达终点 */ 20 if (deads.contains(cur)) 21 continue; 22 if (q2.contains(cur)) 23 return step; 24 visited.add(cur); 25 26 /* 将一个节点的未遍历相邻节点加入集合 */ 27 for (int j = 0; j < 4; j++) { 28 String up = plusOne(cur, j); 29 if (!visited.contains(up)) 30 temp.add(up); 31 String down = minusOne(cur, j); 32 if (!visited.contains(down)) 33 temp.add(down); 34 } 35 } 36 /* 在这里增加步数 */ 37 step++; 38 // temp 相当于 q1 39 // 这里交换 q1 q2,下一轮 while 就是扩散 q2 40 q1 = q2; 41 q2 = temp; 42 } 43 return -1; 44 }
参考链接:https://mp.weixin.qq.com/s/WH_XGm1-w5882PnenymZ7g