線段樹知識點總結

專欄 | 九章算法
網址 | 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教育領域的深耕者
相關文章
相關標籤/搜索