线段树知识点总结

专栏 | 九章算法
网址 | www.jiuzhang.com程序员


线段树专题面试

线段树入门问题算法

给出数列[1 4 2 3],求给定区间的最大值
例:query(0,1) = 4 query(2,3) = 3 query(0,3) = 4数组


解题思路分析微信

一道题可不能够用线段树来作,基本是看这道题的操做有没有区间的性质。也就是在一个区间上的操做是否能够转化为两个子区间上的操做。
从这题能够看出ui

区间(a,b)的最大值和区间(b,c)的最大值中
取较大的就是区间(a,c)的最大值3d

很明显能够看出这个操做是具备区间的性质。

code

套路:几种常见的线段树的套路cdn

  1. 求区间的和,积,最大值,最match小值,gcd等
  2. 以当前结点的值做为结点处理,好比给出N个数,再给一个数,问比这个数大的有多少个(固然,用树状数组能够很好的处理,但有修改时,线段树就会方便不少)
  3. 区间加减同一个值,或者区间同时赋一个值(在面试中,一般不会问到,算法竞赛中会常常用到)

构造:一颗线段树的构造就是根据区间的性质的来构造的blog

区间划分大概就是上述的区间划分。能够看出每次都将区间的长度一分为二,数列长度为n,因此线段树的高度是log(n),这是不少高效操做的基础。
上述的区间存储的只是区间的左右边界。咱们能够将区间的最大值加入进来。

区间的第三维就是区间的最大值

加这一维的时候只须要在建完了左右区间以后,根据左右区间的最大值来更新当前区间的最大值便可。
由于每次将区间的长度一分为二,全部创造的节点个数为
n + 1/2 n + 1/4 n + 1/8 n + ...
= (1 + 1/2 + 1/4 + 1/8 + ...)
n
= 2n
因此构造线段树的时间复杂度和空间复杂度都为O(n)

代码1:线段树构造代码模板

区间查询:构造线段树的目的就是为了更快的查询。

给定一个区间,要求区间中最大的值。
线段树的区间查询操做就是将当前区间分解为较小的子区间,而后由子区间的最大值就能够快速获得须要查询区间的最大值。

query(1,3) = max(query(1,1),query(2,3)) = max(4,3) = 4

上述例子将(1,3)区间分为了(1,1)和(2,3)两个区间,由于(1,1)和(2,3)区间的最大值事先已经记录好了,因此直接拿来用就能够了。

层数:每一层最多查询4个区间

考虑长度为16的序列构形成的线段树,区间(0,15)。查询区间(1,14)。

第一层会查询 (1,7) (8,15)
第二层会查询 (1,3) (4,7) (8,11) (12,14)
第三层会查询 (1,1) (2,3) (12,13) (14,14)
第四层会查询 (1,1) (14,14)

由于是连续的,中间那部分会直接算出来,而后两边的两端继续往下,仍是4个区间。
由于线段树的高度为log(n),因此查询的时间复杂度为O(log(n))

代码2:线段树区间查询模板

单点更新:更新序列中的一个节点

如何把这种变化体现到线段树中去?

例如,将序列中的第4个点更新为5,要变更3个区间中的值,分别为[3,3],[2,3],[0,3]

能够这样想,改动一个节点,与这个节点对应的叶子节点须要变更。由于叶子节点的值的改变可能影响到父亲节点,而后叶子节点的父亲节点也可能须要变更。
因此须要从叶子节点一路走到根节点,去更新线段树上的值。由于线段树的高度为log(n),因此更新序列中一个节点的复杂度为log(n)。

代码3:线段树单点更新模板

若是须要区间的最小值或者区间的和。和构造的时候同理。


相关Lintcode面试题

线段树构造

www.lintcode.com/zh-cn/probl…
www.lintcode.com/zh-cn/probl…

线段树单点更新

www.lintcode.com/zh-cn/probl…

线段树区间查询

www.lintcode.com/zh-cn/probl…
www.lintcode.com/zh-cn/probl…

线段树综合

www.lintcode.com/zh-cn/probl…
www.lintcode.com/zh-cn/probl…
www.lintcode.com/zh-cn/probl…
www.lintcode.com/zh-cn/probl…
www.lintcode.com/zh-cn/probl…



欢迎关注个人微信公众号:九章算法(ninechapter)。
精英程序员交流社区,按期发布面试题、面试技巧、求职信息等

九章算法,IT教育领域的深耕者
相关文章
相关标签/搜索