高级数据结构1—初识树状数组—快速求得前缀和和修改某一元素值

本文介绍了树状数组的基本原理,包括其在快速求前缀和、修改元素值方面的优势,以及在实际问题如楼兰图腾、区间和检索等中的应用实例。通过理解区间元素个数的计算和父节点查找,掌握如何使用树状数组优化nlogn复杂度问题。

- 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~

  • 本人Gitee账号:路由器,欢迎关注获取博客内容源码。

  树状数组和其他的高级数据结构不同,它非常的好写,同时解决问题也比较局限,所以树状数组的题目的难度主要集中在思考而非代码。

一、基本原理

  树状数组可以解决两个操作:快速的求前缀和修改某一个数,这两个操作都是O(logn)的。

  这两个操作如果我们直接来操作:

  • 存原数组,前缀和O(N),修改一个数O(1)
  • 维护前缀和,前缀和O(1),修改一个数O(N)

  有一种鱼和熊掌不可兼得的感觉,但是我们的题目中时间复杂度一般取决于最糟糕的时间复杂度,所以如果有n次查询,那么复杂度会达到O(n^2)。树状数组有一个折中的思想,它让这两个操作的时间复杂度都变成了O(logn),这样总时间复杂度就是O(nlogn),就会快很多了。

  它是一种基于二进制的方法来解决这个问题的。

  假设我们有一个数x,其二进制表示为:
x = 2 i k + 2 i k − 1 + . . . + 2 i 1 i k > = i k − 1 > = . . . > = i 1 x = 2^{i_k} + 2^{i_{k - 1}} + ...+2^{i_{1}}\\ i_{k}>=i_{k-1}>=...>=i_1 x=2ik+2ik1+...+2i1ik>=ik1>=...>=i1
  假设我们想求的是下标为1~x的总和,那么我们可以把1~x这个区间划分成k部分:
( x − 2 i 1 , x ] ( x − 2 i 1 − 2 i 2 , x − 2 i 1 ] . . . ( 0 , x − 2 i 1 − 2 i 2 − . . . − 2 i k − 1 ] (x-2^{i_1},x]\\(x-2^{i_1}-2^{i_2}, x-2^{i_1}]\\...\\(0,x-2^{i_1}-2^{i_2}-...-2^{i_{k-1}}] (x2i1,x](x2i12i2,x2i1]...(0,x2i12i2...2ik1]
  这样就把下标为1~x这个区间划分成了logx份,这样如果算1~x的总和,只需要求logx个区间的和就能算出来了。

  这个思想就是让我们在logn的时间复杂度中使用前缀和的思想。

  下面来看看区间中元素的个数和区间右端点有什么关系:
( x − 2 i 1 , x ] , 元 素 个 数 2 1 i 个 ( x − 2 i 1 − 2 i 2 , x − 2 i 1 ] , 元 素 个 数 2 2 i 个 . . . ( 0 , x − 2 i 1 − 2 i 2 − . . . − 2 i k − 1 ] , 元 素 个 数 2 k i 个 (x-2^{i_1},x], 元素个数2^i_1个\\ (x-2^{i_1}-2^{i_2}, x-2^{i_1}],元素个数2^i_2个\\ ...\\ (0,x-2^{i_1}-2^{i_2}-...-2^{i_{k-1}}],元素个数2^i_k个 (x2i1,x],21i(x2i12i2,

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值