给定一个数组,需要对数组的元素进行修改,并查询区间范围内的和。
乍一看,这是线段树嘛!
其实还有一种数据结构叫做树状数组,
树状数组这一数据结构能使得这两种操作的时间复杂度都是
关于树状数组,如果不够明白的话,可以看下面几篇文章:
树状数组(Binary Indexed Tree),看这一篇就够了blog.csdn.net下面介绍树状数组的Python实现以及应用:
首先定义树状数组的 API:
- 初始化 传入一个长度为
的初始数组,需要时间
- 函数
query(begin: int, end: int) -> int
,查询数组的和 - 函数
update(idx: int, val: int)
,将初始数组的第位置更新为,注意不是在第位置加上
class BinaryIndexTree:
def __init__(self, array: list):
'''初始化,总时间 O(n)'''
self._array = [0] + array
n = len(array)
for i in range(1, n + 1):
j = i + (i & -i)
if j < n + 1:
self._array[j] += self._array[i]
def lowbit(self, x: int) -> int:
return x & (-x)
def update(self, idx: int, val: int):
'''将原数组idx下标更新为val, 总时间O(log n)'''
prev = self.query(idx, idx + 1) # 计算出原来的值
idx += 1
val -= prev # val 是要增加的值
while idx < len(self._array):
self._array[idx] += val
idx += self.lowbit(idx)
def query(self, begin: int, end: int) -> int:
'''返回数组[begin, end) 的和'''
return self._query(end) - self._query(begin)
def _query(self, idx: int) -> int:
'''计算数组[0, idx)的元素之和'''
res = 0
while idx > 0:
res += self._array[idx]
idx -= self.lowbit(idx)
return res
在LeetCode中,有一道题就非常直接的考察了树状数组
力扣leetcode-cn.com