來源:https://leetcode-cn.com/problems/open-the-lock/solution/wo-xie-liao-yi-tao-bfs-suan-fa-kuang-jia-jian-dao-/
又是看這個大佬學習的,下面我自己總結一下,並且記錄一下遇到的使用BFS的題目,驗證一下這個套路的可行性。一直比較討厭這種題,因爲沒有總結出一套框架來。(現在回溯熟悉的差不多了 哈哈哈哈)
一.背景和框架
BFS本質:本質上就是一幅「圖」,讓你從一個起點,走到終點,問最短路徑
下面是算法的框架:
// 計算從起點 start 到終點 target 的最近距離
int BFS(Node start, Node target) {
Queue<Node> q; // 核心數據結構
Set<Node> visited; // 避免走回頭路
q.offer(start); // 將起點加入隊列
visited.add(start);
int step = 0; // 記錄擴散的步數
while (q not empty) {
int sz = q.size();
/* 將當前隊列中的所有節點向四周擴散 */
for (int i = 0; i < sz; i++) {
Node cur = q.poll();
/* 劃重點:這裏判斷是否到達終點 */
if (cur is target)
return step;
/* 將 cur 的相鄰節點加入隊列 */
for (Node x : cur.adj())
if (x not in visited) {
q.offer(x);
visited.add(x);
}
}
/* 劃重點:更新步數在這裏 */
step++;
}
}
二.例題
1.二叉樹的最小高度
int BFS(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
// root 本身就是一層,depth 初始化爲 1
int depth = 1;
while (!q.isEmpty()) {
int sz = q.size();
/* 將當前隊列中的所有節點向四周擴散 */
for (int i = 0; i < sz; i++) {
TreeNode cur = q.poll();
/* 判斷是否到達終點 */
if (cur.left == null && cur.right == null)
return depth;
/* cur 的相鄰節點加入隊列 */
if (cur.left != null)
q.offer(cur.left);
if (cur.right != null)
q.offer(cur.right);
}
/* 這裏增加步數 */
depth++;
}
return depth;
}
解釋:
- Queue 在Java中用LinkedList<>()來創建實例
- 這裏不用加vistied記錄走過的路徑是因爲樹結構本身
- 判斷是否達到終點:左子節點和右子節點均爲null