【题目】
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例 1:
输入:root = [1,2,3,4,5,6]
输出:6
示例 2:
输入:root = []
输出:0
示例 3:
输入:root = [1]
输出:1
提示:
树中节点的数目范围是[0, 5 * 104]
0 <= Node.val <= 5 * 104
题目数据保证输入的树是 完全二叉树
进阶:遍历树来统计节点是一种时间复杂度为 O(n) 的简单解决方案。你可以设计一个更快的算法吗?
【代码】
【方法1:迭代】
class Solution:
def countNodes(self, root: TreeNode) -> int:
if not root:
return 0
queue=[root]
cnt=0
while queue:
root=queue.pop(0)
if not root:
return cnt
cnt+=1
queue.append(root.left)
queue.append(root.right)
return cnt
【方法2:递归——不讲武德】
class Solution:
def countNodes(self, root: TreeNode) -> int:
if not root:
return 0
return self.countNodes(root.left)+self.countNodes(root.right)+1
class Solution:
def dfs(self,root):
if not root:
return 0
return self.dfs(root.left)+self.dfs(root.right)+1
def countNodes(self, root: TreeNode) -> int:
return self.dfs(root)
【方法3:】
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.cnt=0
def getDepth(self,root):
if not root:
return 0
return max(self.getDepth(root.left),self.getDepth(root.right))+1
def countNodes(self, root: TreeNode) -> int:
while root:
left_dep=self.getDepth(root.left)
right_dep=self.getDepth(root.right)
if left_dep==right_dep:
self.cnt+=pow(2,left_dep)
root=root.right
else:
self.cnt+=pow(2,right_dep)
root=root.left
return self.cnt
class Solution:
def __init__(self):
self.cnt=0
def getDepth(self,root):
if not root:
return 0
return max(self.getDepth(root.left),self.getDepth(root.right))+1
def countNodes(self, root: TreeNode) -> int:
if not root:
return 0
left_dep=self.getDepth(root.left)
while root:
right_dep=self.getDepth(root.right)
if left_dep==right_dep:
self.cnt+=2**left_dep
root=root.right
else:
self.cnt+=2**right_dep
root=root.left
left_dep-=1
return self.cnt
【方法4:二分查找+位运算】重点学习
class Solution:
def exits(self,index,root1,level):
k=1<<(level-1)
while root1 and k>0:
if index & k:
root1=root1.right
else:
root1=root1.left
k>>=1
return root1
def countNodes(self, root: TreeNode) -> int:
if not root:
return 0
level=-1
root1=root
while(root):
level+=1
root=root.left
low=1<<level
high=(1<<(level+1))-1
while low<high:
mid=(high-low+1)//2+low
#mid存在 则往右侧找
if self.exits(mid,root1,level):
low=mid
else:
high=mid-1
#mid不存在 则往左侧找
return low