1. 程式人生 > >LeetCode刷題Easy篇求二叉樹的最大深度

LeetCode刷題Easy篇求二叉樹的最大深度

題目

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Note: A leaf is a node with no children.

Example:

Given binary tree [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

return its depth = 3.

我的嘗試

遞迴嘗試

這個很明顯可以用遞迴來解決,程式碼如下,測試通過:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
       if(root==null){
           return 0;
       }
       return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
    }
}

非遞迴嘗試

我按照之前總結對二叉樹處理對方式,寫出了程式碼框架:

1 root入stack

2,while stack is not empty

3. 處理彈出的棧元素,判斷是否有left right,入stack。

無法解法這個題目的原因是:

左右節點重複計數?左右節點都入stack後,彈出左節點,加1,彈出右節點也加1,如何取出重複?

看了討論,發現當時我也感覺到了這個方法,但是沒有成熟,其實很簡單。迴圈stack直到size為0,這樣同一層的元素都可以出來,此時我們增加1.

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
      if(root==null) return 0;
       Deque<TreeNode> stack=new LinkedList();
       stack.push(root);
       int count=0;
       while(!stack.isEmpty()){
           int size=stack.size();
           //這個迴圈,每層元素的下一層一次性入stack,防止左右子樹重複計數
           while(size-->0){
              TreeNode treeNode=stack.pop();
              if(treeNode.left!=null){
                 stack.push(treeNode.left);
               }
              if(treeNode.right!=null){
               stack.push(treeNode.right);
              } 
           }
           count++;
       }
        return count;
    }
}

本來邏輯感覺是正確的,但是測試結果不對,我梳理也沒有發現問題,後來看別人的程式碼,發現區別點,是Deque的api用的不對。

剛開始,stack裡面是1,pop出1,然後2和3進入stack。在size迴圈中,3先pop出stack,所以3的孩子節點將會入stack,這個時候2並沒有出stack!!!跟我預期的是不一樣的,這就是我錯誤的地方

怎麼解決?應該用佇列,而不是棧。這個程式碼其實是廣度有限遍歷的演算法。所以廣度優先遍歷利用的是佇列,而深度優先遍歷用的是棧!

修改後程式碼如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
      if(root==null) return 0;
       Queue<TreeNode> queue=new LinkedList();
       queue.add(root);
       int count=0;
       while(!queue.isEmpty()){
           int size=queue.size();
           //這個迴圈,每層元素的下一層一次性入stack,防止左右子樹重複計數
           while(size-->0){
              TreeNode treeNode=queue.poll();
              if(treeNode.left!=null){
                 queue.add(treeNode.left);
               }
              if(treeNode.right!=null){
               queue.add(treeNode.right);
              } 
           }
           count++;
       }
        return count;
    }
}

如果該用Deque,也可以,程式碼如下:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
      if(root==null) return 0;
       Deque<TreeNode> queue=new LinkedList();
       queue.add(root);
       int count=0;
       while(!queue.isEmpty()){
           int size=queue.size();
           //這個迴圈,每層元素的下一層一次性入stack,防止左右子樹重複計數
           while(size-->0){
              TreeNode treeNode=queue.poll();
              if(treeNode.left!=null){
                 queue.add(treeNode.left);
               }
              if(treeNode.right!=null){
               queue.add(treeNode.right);
              } 
           }
           count++;
       }
        return count;
    }
}