📅  最后修改于: 2023-12-03 15:12:44.171000             🧑  作者: Mango
给定一个二叉树,实现以下操作:
update(i, val)
:将第 i
个节点的值更新为 val
。preSum(i)
:返回前 i 个节点的值的和,其中 i
是节点的编号。 1 ----> 2
/ \ / \
3 4 5 6
bst = BST(6)
bst.update(4, 7) # 节点 4 的值更新为 7
bst.preSum(5) # 返回 15(节点 1 ~ 5 的和为 15)
为了能够快速计算前 i 个节点的和,我们需要为每个节点维护一个前缀和,表示以这个节点为根的子树中所有节点的值的和。
对于每个节点,我们可以通过其父节点的前缀和和它自身的值计算出自身的前缀和,即:
prefixSum[node] = prefixSum[parent] + node.val
当调用 preSum(i)
时,我们只需要在树中从节点 i 开始向上遍历到根节点,累加节点的前缀和即可。
更新操作比较简单,只需要找到要更新的节点,更新其值并重新计算节点及其祖先节点的前缀和即可。
我们可以定义一个节点类 Node
,其中包含节点编号 index
、节点值 val
、左子节点 left
、右子节点 right
和前缀和 prefixSum
。然后定义一个二叉搜索树类 BST
,其中包含树的大小 size
和根节点 root
,以及以下方法:
__init__(self, n)
:初始化根节点为 None,大小为 n
的二叉搜索树。_find(self, i)
:寻找节点编号为 i
的节点,如果不存在则返回 None。update(self, i, val)
:将节点编号为 i
的节点的值更新为 val
。_updatePrefixSum(self, node)
:递归更新节点 node
及其祖先节点的前缀和。preSum(self, i)
:返回前 i
个节点的值的和。class Node:
def __init__(self, index, val):
self.index = index
self.val = val
self.left = None
self.right = None
self.prefixSum = val
class BST:
def __init__(self, n):
self.size = n
self.root = None
def _find(self, i):
node = self.root
while node:
if i < node.index:
node = node.left
elif i > node.index:
node = node.right
else:
return node
return None
def update(self, i, val):
node = self._find(i)
if node:
delta = val - node.val
node.val = val
node.prefixSum += delta
self._updatePrefixSum(node)
def _updatePrefixSum(self, node):
while node:
node.prefixSum = node.val
if node.left:
node.prefixSum += node.left.prefixSum
if node.right:
node.prefixSum += node.right.prefixSum
node = node.parent
def preSum(self, i):
node = self._find(i)
prefixSum = 0
while node:
prefixSum += node.prefixSum
node = node.parent
return prefixSum