111. Minimum Depth of Binary Tree windliang

題目描述(簡單難度)

在這裏插入圖片描述
返回從根節點到葉子節點最小深度。

解法一 遞歸

和 104 題 有些像,當時是返回根節點到葉子節點的最大深度。記得當時的代碼很簡單。

public int maxDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}

這道題是不是隻要把Math.max,改成Math.min就夠了。

public int minDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}

粗略的想一下,似乎很完美,比如題目給的例子

     3
    / \
   9   20
      /  \
     15   7

根據代碼走一遍,root.left返回 1,root.right返回 2,選較小的1,加上 1 返回結果2,完美符合結果。

但如果是下邊的樣子呢?

     3
    / \
   9   20
  /   /  \
 8   15   7

區別在於有一個子樹的擁有一個孩子,另一個孩子爲空。

這樣利用上邊的算法,當考慮9這個子樹的時候,左孩子會返回1,由於它的右孩子爲null,右孩子會返回0,選較小的0,加上 1 返回結果1給上一層。

也就是最頂層的root.left依舊得到了 1,但明顯是不對的,對於左子樹,應該是從 9 到 8,深度應該是 2。

所以代碼上需要修正這個算法,再想想題目要求是從根節點到葉節點,所以如果有一個子樹的左孩子或者右孩子爲null了,那就意味着這個方向不可能到達葉子節點了,所以就不要再用Min函數去判斷了。

我對代碼的修正如下:

class TreeNode{
	int val;
	TreeNode left;
	TreeNode right;
	TreeNode(int x){val=x;}
}

public class Minimum_Depth_of_Binary_Tree {
	
	public static int minDepth(TreeNode root) {
		
	if(root==null) return 0;
	
	return minDepthHelper(root);
	
    }
	
	private static int minDepthHelper(TreeNode root) {
		
		if(root.left==null && root.right==null) return 1;
		//左孩子爲空,只考慮右孩子的方向
		if(root.left==null) return minDepthHelper(root.right)+1;
		//右孩子爲空,只考慮左孩子的方向
		if(root.right==null) return minDepthHelper(root.left)+1;
		
		return Math.min(minDepthHelper(root.left), minDepthHelper(root.right))+1;
	}
	
	public static void main(String args[]) {
		TreeNode[] node=new TreeNode[6];
		node[0]=new TreeNode(3);
		node[1]=new TreeNode(9);
		node[2]=new TreeNode(20);
		node[3]=new TreeNode(8);
		node[4]=new TreeNode(15);
		node[5]=new TreeNode(7);
		node[0].left=node[1];
		node[0].right=node[2];
		node[1].left=node[3];
		node[2].left=node[4];
		node[2].right=node[5];
		int ans=minDepth(node[0]);
		System.out.println(ans);
	}
}

其實也是可以把兩個函數合在一起的,參考這裏。

public int minDepth(TreeNode root) {
    if (root == null){
        return 0;
    }   
    // 左孩子爲空,只考慮右孩子的方向
    if (root.left == null) {
        return minDepth(root.right) + 1;
    }
    // 右孩子爲空,只考慮左孩子的方向
    if (root.right == null) {
        return minDepth(root.left) + 1;
    } 
    return Math.min(minDepth(root.left),minDepth(root.right)) + 1;
}

此外,還有一個想法,覺得不錯,大家可以看看,參考這裏。

public int minDepth(TreeNode root) {
    if (root == null) { 
        return 0;
    }
    if (root.left != null && root.right != null) {
        return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
    } else {
        return Math.max(minDepth(root.left), minDepth(root.right)) + 1;
    } 
}

當左孩子爲空或者右孩子爲空的時候,它就直接去選一個較大深度的,因爲較小深度一定是爲空的那個孩子,是我們不考慮的。

上邊三個算法本質上其實是一樣的,就是解決了一個孩子爲空另一個不爲空的問題,而對於104 題 沒有出現這個問題,是因爲我們選的是max,所以不用在意是否有一個爲空。

解法二 BFS

104 題 也提供了BFS的方案,利用一個隊列進行層次遍歷,用一個 level 變量保存當前的深度,代碼如下:

public int maxDepth(TreeNode root) {

    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    List<List<Integer>> ans = new LinkedList<List<Integer>>();
    if (root == null)
        return 0;
    queue.offer(root);
    int level = 0;
    while (!queue.isEmpty()) {
        int levelNum = queue.size(); // 當前層元素的個數
        for (int i = 0; i < levelNum; i++) {
            TreeNode curNode = queue.poll();
            if (curNode != null) {
                if (curNode.left != null) {
                    queue.offer(curNode.left);
                }
                if (curNode.right != null) { 
                    queue.offer(curNode.right);
                }
            }
        }
        level++;
    }
    return level;
}

對於這道題就比較容易修改了,只要在 for 循環中判斷當前是不是葉子節點,如果是的話,返回當前的 level 就可以了。此外要把level初始化改爲1,因爲如果只有一個根節點,它就是葉子節點,而在代碼中,level 是在 for循環以後才++的,如果被提前結束的話,此時應該返回1。

public int minDepth(TreeNode root) {
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    List<List<Integer>> ans = new LinkedList<List<Integer>>();
    if (root == null)
        return 0;
    queue.offer(root);
    /**********修改的地方*****************/
    int level = 1;
    /***********************************/
    while (!queue.isEmpty()) {
        int levelNum = queue.size(); // 當前層元素的個數
        for (int i = 0; i < levelNum; i++) {
            TreeNode curNode = queue.poll();
            if (curNode != null) {
                /**********修改的地方*****************/
                if (curNode.left == null && curNode.right == null) {
                    return level;
                }
                /***********************************/
                if (curNode.left != null) {
                    queue.offer(curNode.left);
                }
                if (curNode.right != null) {
                    queue.offer(curNode.right);
                }
            }
        }
        level++;
    }
    return level;
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章