一. 背景
那么我们为什么要用树状数组呢?
在解决一些区间求和的问题中 , 简单描述就是,对于一个给定的数组A,希望能够设计一个update函数来修改其中一个数的值,然后再设计一个sum函数来计算数组下标再给定参数l和r之间的值之和。关键点在于这两个函数可能被无数次调用,所以需要保证两个函数的复杂度都要小。
平时我们对这类问题常用的两种方法是 :
1>暴力算法
update
函数采用对数组直接修改的方式。
O(1) ,
对于sum
函数,返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的和,但是这道题的操作数很大,会超时。
O(n)
2>前缀和算法
sum函数,考虑前缀和的方法,也就是采用动态规划的方法,设计一个新的数组sums来表示前缀和。
其基本思想为,
sums
[i]表示A[0]+A[1]+A[2]+...+A[i-1]。具体操作的时候我们只需要设置sums[i] = sums[i-1]+A[i-1]即可。
如果希望计算数组下标从l到r的区间和,只需要计算sums[r+1]-sums[l]即可。希望使用这种方式达到简化计算复杂度的目的。 但是,这时候需要考虑update函数,当我们对数组A直接进行修改值之后,我们发现sums数组也需要进行修改。
举个栗子:
原数组:A= {1,2,3,4,5}