專欄 | 九章算法
網址 | 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
構造:一顆線段樹的構造就是根據區間的性質的來構造的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…