首先最直观的想法,对于一个普通二叉树,我们想知道节点个数,递归得到:左子树节点数目 + 右子树节点数目 + 1(当前节点),返回给上层函数(告诉他爹,我这有这么多节点~)
没啥技巧的后序就行
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
def post_recursion(node):
if not node:
return 0
num_l = post_recursion(node.left)
num_r = post_recursion(node.right)
return num_l + num_r + 1
return post_recursion(root)
但这没有利用完全二叉树的性质,这里要区分满二叉树和完全二叉树(自己查定义)。对于一个满二叉树,其深度为n的话,其节点数目为2**n - 1(等比数列求和不会的话可以重开了)。那如何哦快速判断一棵树,它是不是满二叉树呢?从根节点往左走,得到最左深度maxDepthL,同理从根节点往右走,得到最右深度maxDepthR,如果maxDepthL == maxDepthR,那么就是一课满二叉树,直接计算返回,不然继续向下递归,总能得到满二叉树,这样可以不用遍历所有节点。
class Solution:
def countNodes(self, root: Optional[TreeNode]) -> int:
def post_traversal(node):
if not node:
return 0
cur = node
maxDepthL = 0
while cur:
maxDepthL += 1
cur = cur.left
cur = node
maxDepthR = 0
while cur:
maxDepthR += 1
cur = cur.right
if maxDepthL == maxDepthR:
return 2 ** maxDepthL - 1
numL = post_traversal(node.left)
numR = post_traversal(node.right)
return numL + numR + 1
return post_traversal(root)