想了解更多數據結構以及算法題,可以關注微信公衆號“數據結構和算法”,每天一題爲你精彩解答。也可以掃描下面的二維碼關注
題目描述
給定一個二叉樹,找出其最小深度。
最小深度是從根節點到最近葉子節點的最短路徑上的節點數量。
說明: 葉子節點是指沒有子節點的節點。
示例:
給定二叉樹 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最小深度 2。
問題分析:
這題其實不難,看到這道題我們首先想到的是BFS,就是一層一層的遍歷,如果某一層的某個節點沒有子節點了,我們就返回這個節點的層數即可。
比如上面的9在第二層,他沒有子節點了,我們直接返回他所在的層數2即可,沒必要在遍歷第3層了。代碼很簡單,我們來看下。
1,非遞歸寫法
public int minDepth(TreeNode root) {
if (root == null)
return 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);//入隊
int level = 0;
while (!queue.isEmpty()) {//隊列不爲空就繼續循環
level++;
int levelCount = queue.size();
for (int j = 0; j < levelCount; j++) {
TreeNode node = queue.poll();//出隊
//如果當前node節點的左右子樹都爲空,直接返回level即可
if (node.left == null && node.right == null)
return level;
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}
return -1;
}
2,遞歸寫法
我們還可以使用遞歸的方式,返回Math.min(左子樹的深度,右子樹的深度)+1,看起來很有道理,但有一個問題,如果左右子樹都不爲空或者都爲空是沒問題的。但如果左右子樹一個爲空一個不爲空,就會有問題了,因爲爲空的那個子節點的深度是0,我們不能用它,所以這裏要有個判斷。
比如下面7的左子樹的深度是0,但他還有右子樹,所以我們不能選擇深度最小的(因爲這時7的左子樹的深度是0)。
public int minDepth(TreeNode root) {
if (root == null)
return 0;
//左子樹的最小深度
int left = minDepth(root.left);
//右子樹的最小深度
int right = minDepth(root.right);
//如果left和right都爲0,我們返回1即可,
//如果left和right只有一個爲0,說明他只有一個子結點,我們只需要返回它另一個子節點的最小深度+1即可。
//如果left和right都不爲0,說明他有兩個子節點,我們只需要返回最小深度的+1即可。
return (left == 0 || right == 0) ? left + right + 1 : Math.min(left, right) + 1;
}
或者我們還可以換種方式
public static int minDepth(TreeNode root) {
if (root == null)
return 0;
//如果左子樹等於空,我們返回右子樹的最小高度+1
if (root.left == null)
return minDepth(root.right) + 1;
//如果右子樹等於空,我們返回左子樹的最小高度+1
if (root.right == null)
return minDepth(root.left) + 1;
//如果左右子樹都不爲空,我們返回左右子樹深度最小的那個+1
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}