代码随想录算法训练营第十六天 | 104. 二叉树的最大深度、559. N 叉树的最大深度、111. 二叉树的最小深度、222. 完全二叉树的节点个数

93 阅读3分钟

104. 二叉树的最大深度

代码随想录视频讲解

代码随想录文章讲解

高度,深度

本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。

  • 二叉树节点的深度:指从根节点该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)

  • 二叉树节点的高度:指从该节点叶子节点的最长简单路径边的条数后者节点数(取决于高度从0开始还是从1开始)

  • 而根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。

迭代法(使用队列)

  • 层次遍历,每遍历一层,depth++
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        
        depth = 0
        q = deque([root])
        while q:
            l = len(q)
            depth += 1
            for _ in range(l):
                cur = q.popleft()
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
                    
        return depth

递归法

  • 最大深度就是左右子树中较大的深度加上自身的一层
class Solution:
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """ 
        if root is None: 
            return 0 
        else: 
          # left -> right -> root (post-order)
            left_height = self.maxDepth(root.left) 
            right_height = self.maxDepth(root.right) 
            return max(left_height, right_height) + 1 

559. N 叉树的最大深度

迭代法

  • 逻辑对于使用层次遍历来说没有区别
# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def maxDepth(self, root: 'Node') -> int:
        if not root:
            return 0
        
        depth = 0
        q = deque([root])
        while q:
            l = len(q)
            depth += 1
            for _ in range(l):
                cur = q.popleft()
                for c in cur.children:
                    q.append(c)
                    
        return depth

递归法

# Time complexity: O(N)
# Space complexity: average O(logN); worst O(N)
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: Node
        :rtype: int
        """
        if root is None: 
            return 0 
        elif root.children == []:
            return 1
        else: 
            height = [self.maxDepth(c) for c in root.children]
            return max(height) + 1# or
class Solution:
    def maxDepth(self, root: 'node') -> int:
        if not root:
            return 0
​
        depth = 0
        for c in root.children:
            depth = max(depth, self.maxDepth(c))
​
        return depth + 1

111. 二叉树的最小深度

代码随想录视频讲解

代码随想录文章讲解

迭代法(层次遍历)

  • 找到叶子结点就返回当前depth
class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
​
        depth = 0
        q = deque([root])
        while q:
            l = len(q)
            depth += 1
            for _ in range(l):
                cur = q.popleft()
                if not cur.left and not cur.right:
                    return depth
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
​
        return depth

递归法

  • 注意,当左右子树有一个为空时,另一个的最小深度加1才是当前的最小深度
class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
​
        # left-subtree is empty
        if not root.left and root.right:
            return 1 + self.minDepth(root.right)
        # right-subtree is empty
        if root.left and not root.right:
            return 1 + self.minDepth(root.left)
​
        # have both left and right subtrees
        return min(self.minDepth(root.left), self.minDepth(root.right)) + 1

222. 完全二叉树的节点个数

代码随想录视频讲解

代码随想录文章讲解

完全二叉树的特点

  • 除了最后一层的叶子节点,都是满的
  • 完全满的二叉树的节点个数是2^k-1,k是层数
  • 所以我们可以利用比较左右子树的height值,来加快计算速度。(只需要数最后一层的节点个数)

迭代法(层次遍历)

  • 一层层数节点数
  • 没有用到完全二叉树的特性
# Time complexity: O(N)
# Space complexity: O(N)
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
​
        count = 0
        q = deque([root])
        while q:
            l = len(q)
            for _ in range(l):
                cur = q.popleft()
                count += 1
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
​
        return count

递归法

  • 利用了完全二叉树的特性进行计算
# Time complexity: O(logN * logN)
# Space complexity: O(logN)
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        
        left_height = 0
        cur = root
        while cur:
            left_height += 1
            cur = cur.left
        
        right_height = 0
        cur = root
        while cur:
            right_height += 1
            cur = cur.right
            
        if left_height == right_height:
            return (2**right_height - 1)
        
        # current node + left-subtree count + right-subtree count
        return 1 + self.countNodes(root.left) + self.countNodes(root.right)