赞
踩
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例1:
输入:root = [1,2,3,4,5,6]
输出:6
示例2:
输入:root = []
输出:0
示例3:
输入:root = [1]
输出:1
思路:
很自然想到遍历整个树,统计完全二叉树的节点数
class Solution:
def countNodes(self, root: TreeNode) -> int:
if not root: return 0
queue = [root]
total = 0
while queue:
# 累加每层的节点数
total += len(queue)
queue = [n for node in queue for n in [node.left, node.right] if n]
return total
也可以先计算出树的深度,这样只要找到最后一层的节点数即可,找到最后一层的节点,可以使用二分法
class Solution: # 计算树的深度 def getDepth(self, root): cur, dep = root, 0 while cur.left: cur, dep = cur.left, dep + 1 return dep # 判断位置是否有节点 # 最后一层的结点位置为 2**depth 至 2**(depth + 1) - 1 # 可以看到除了第一个高位外,其余位置代表着该节点在树的走向,比如11的二进制为1011,后面三位为011,那么代表着左右右节点方向 # 这样我们可以通过按位与的方式获取当前是指向左子节点还是右子节点 # 将当前比较的位设置为1,其他位置为0即可 def hasNode(self, root, index, depth): bit = 1 << (depth - 1) cur = root while depth > 0: if bit & index > 0: cur = cur.right else: cur = cur.left depth -= 1 bit = bit >> 1 return cur != None def countNodes(self, root: TreeNode) -> int: if not root: return 0 dep = self.getDepth(root) print(dep) start, end = 1 << dep, (1 << (dep + 1)) - 1 # 使用二分法找到最后一个节点 while start < end: mid = (start + end + 1) >> 1 if self.hasNode(root, mid, dep): start = mid else: end = mid - 1 return start
完全二叉树 是每一层(除最后一层外)都是完全填充(即,节点数达到最大)的,并且所有的节点都尽可能地集中在左侧。
设计一种算法,将一个新节点插入到一个完整的二叉树中,并在插入后保持其完整。
实现 CBTInserter 类:
思路:
完全二叉树需要上一层完全填充后再插入下一层,可以通过层序遍历,记录最后已经完全填充的层,找到下一层还未填充的位置,那么插入的时候,只需要在指定位置继续填充即可。
class CBTInserter: def __init__(self, root: TreeNode): self.root = root # 层node队列 self.queue = [self.root] self.index = 0 while self.queue: # 遍历层,找到未完全插入的下标 for i, node in enumerate(self.queue): if not node.left or not node.right: self.index = i return self.queue = [n for node in self.queue for n in [node.left, node.right] if n] # 插入的时候,获取未插入完全插入的节点 # 按照左子节点,右子节点的顺序插入 # 如果是右子节点,判断是否该层已经插入完成,如果已经插入完成,更新队列为下一层结点 def insert(self, v: int) -> int: cur = self.queue[self.index] if not cur.left: cur.left = TreeNode(v) return cur.val if not cur.right: cur.right = TreeNode(v) self.index += 1 if self.index > len(self.queue) - 1: self.index = 0 self.queue = [n for node in self.queue for n in [node.left, node.right] if n] return cur.val # 返回根节点 def get_root(self) -> TreeNode: return self.root
给定一个二叉树的 root ,确定它是否是一个 完全二叉树 。
在一个 完全二叉树 中,除了最后一个关卡外,所有关卡都是完全被填满的,并且最后一个关卡中的所有节点都是尽可能靠左的。它可以包含 1 到 2h 节点之间的最后一级 h 。
示例1:
输入:root = [1,2,3,4,5,6]
输出:true
解释:最后一层前的每一层都是满的(即,结点值为 {1} 和 {2,3} 的两层),且最后一层中的所有结点({4,5,6})都尽可能地向左。
示例2:
输入:root = [1,2,3,4,5,null,7]
输出:false
解释:值为 7 的结点没有尽可能靠向左侧。
思路:
由于完全二叉树的特点,除了最后一层,前面层的节点都是填满的,可以使用层序遍历,如果发现层有空节点,并且空节点之后又有不为空的节点,说明此时该层的数据不是满的
class Solution: def isCompleteTree(self, root: TreeNode) -> bool: if not root: return True queue = [root] # 标记是否有空节点 hasNone = False while queue: for i in range(len(queue)): cur = queue.pop(0) # 如果有空节点进行标记 if not cur: hasNone=True continue # 如果已经标记有空节点,但是却发现还有新的不为空的节点,说明不是完全二叉树,返回False if hasNone: return False queue.append(cur.left) queue.append(cur.right) # 遍历完成后,说明是完全二叉树 return True
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。