计算好节点的数量
Posted
技术标签:
【中文标题】计算好节点的数量【英文标题】:Count Number of Good Nodes 【发布时间】:2022-01-11 09:22:32 【问题描述】:problem statement
我无法理解我的代码有什么问题并理解下面的约束。
我的伪代码:
-
遍历树的 Level Order 并构造数组表示(输入实际上是作为单个根给出的,但它们使用数组表示来显示完整的树)
遍历此数组表示,跳过空节点
对于每个节点,我们称其为 X,向上迭代直到到达根节点,检查路径中是否有任何点,
parentNode > nodeX
,这意味着 nodeX 不是一个好节点。
如果节点正常则增加计数器
约束:
二叉树的节点数在 [1, 10^5] 范围内。 每个节点的值都在 [-10^4, 10^4] 之间首先:
我对约束的困惑是,自动化测试正在提供诸如[2,4,4,4,null,1,3,null,null,5,null,null,null,null,5,4,4]
之类的输入,如果我们遵循孩子位于c1 = 2k+1
和c2 = 2k+2
和parent = (k-1)//2
的规则,那么这意味着存在具有值@ 的节点987654329@
其次: 对于上面的输入,我的代码输出8,期望值是6,但是当我从数组中画树的时候,我也觉得答案应该是8!
tree of input
# 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 goodNodes(self, root: TreeNode) -> int:
arrRepresentation = []
queue = []
queue.append(root)
# while queue not empty
while queue:
# remove node
node = queue.pop(0)
if node is None:
arrRepresentation.append(None)
else:
arrRepresentation.append(node.val)
if node is not None:
# add left to queue
queue.append(node.left)
# add right to queue
queue.append(node.right)
print(arrRepresentation)
goodNodeCounter = 1
# iterate over array representation of binary tree
for k in range(len(arrRepresentation)-1, 0, -1):
child = arrRepresentation[k]
if child is None:
continue
isGoodNode = self._isGoodNode(k, arrRepresentation)
print('is good: ' + str(isGoodNode))
if isGoodNode:
goodNodeCounter += 1
return goodNodeCounter
def _isGoodNode(self, k, arrRepresentation):
child = arrRepresentation[k]
print('child: '+str(child))
# calculate index of parent
parentIndex = (k-1)//2
isGood = True
# if we have not reached root node
while parentIndex >= 0:
parent = arrRepresentation[parentIndex]
print('parent: '+ str(parent))
# calculate index of parent
parentIndex = (parentIndex-1)//2
if parent is None:
continue
if parent > child:
isGood = False
break
return isGood
【问题讨论】:
你应该从问题陈述开始。如果没有这种上下文,您的混淆或伪代码对读者来说意义不大。 至于第二个问题,我觉得你画错了树。直到第三级(即,4、1、3),树是正确的。但那一定是 5 是 1 的孩子,然后另一个 5 是这个 5 的孩子。那么 4 和 4 是最后 5 的孩子。 表示树的数组称为二叉堆。空条目表示没有子项(不是该值为空)。看这里:en.wikipedia.org/wiki/Heap_(data_structure) 【参考方案1】:您提供的binary heap 对应于以下层次结构:
tree = [2,4,4,4,None,1,3,None,None,5,None,None,None,None,5,4,4]
printHeapTree(tree)
2
/ \
4 4
/ / \
4 1 3
\
5
在该树中,只有项目值1
的祖先大于自身。其他 6 个节点都很好,因为它们没有比自己更大的祖先(将根视为好)。
请注意,列表中的某些值无法访问,因为它们的父级为 null (None),因此它们不是树的一部分(但这可能是复制/粘贴错误)。如果我们将这些 None 值替换为其他值以使它们成为树的一部分,我们可以看到不可达节点在层次结构中的位置:
t = [2,4,4,4,'*', 1,3,'*',None, 5,None, None,None,None,5,4,4]
printHeapTree(t)
2
__/ \_
4 4
/ \ / \
4 * 1 3
/ / \
* 5 5
/ \
4 4
这可能是 8(不计根为好)与 6(计为好)的结果之间的差异的原因。
你可以找到 printHeapTree() 函数here。
【讨论】:
【参考方案2】:递归可能更容易:
class Node:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
def good_nodes(root, maximum=float('-inf')):
if not root: # null-root
return 0
is_this_good = maximum <= root.val # is this root a good node?
maximum = max(maximum, root.val) # update max
good_from_left = good_nodes(root.left, maximum) if root.left else 0
good_from_right = good_nodes(root.right, maximum) if root.right else 0
return is_this_good + good_from_left + good_from_right
tree = Node(2, Node(4, Node(4)), Node(4, Node(1, Node(5, None, Node(5, Node(4), Node(4)))), Node(3)))
print(good_nodes(tree)) # 6
基本上,递归遍历树,同时更新到目前为止看到的最大数量。在每次迭代中,将根的值与最大值进行比较,必要时增加计数器。
【讨论】:
你是怎么得到这棵树的?我认为当用 0 索引数组表示一棵树时,节点k
的子节点将位于 2k+1
和 2k+2
?
@MPC 您将孩子放在“空”节点下。我认为那些“空”只是表示那里没有节点。所以我在分配孩子时跳过了那些空节点。请注意,例如,我的树中的前 5 个没有左孩子,在列表符号中用“null”表示。以上是关于计算好节点的数量的主要内容,如果未能解决你的问题,请参考以下文章
已知树中非叶子节点的度数和数量,如何计算树中叶子节点的个数?