線段樹 資料結構的簡介和 leetcode 307

2022-05-04 03:36:12 字數 2129 閱讀 9000

之前一直聽說線段樹是乙個很高階很難的資料結構,今天簡單了解了下, 感覺就是二叉樹加幾個全域性變數啊,原來這麼easy?(開個玩笑)

簡單說幾個特點,

1. 每個節點除了存放left,right指標之外,還存著乙個範圍(這個範圍一般是構建線段樹之前陣列的索引範圍), 就是以當前節點為根的情況下,對自己下面所有節點的求交集, 還可以根據你的需求 加一些別的特殊字段,sum,max,min等等

2. 資料集都存在葉子節點上,非葉子節點只做歸納總結

一般還有幾個操作

1. 初始化,就是把乙個陣列初始化成乙個線段樹(關鍵是修改你需求中的特殊字段 sum等)

2. 修改某乙個索引處的數值,同時保證他的祖先節點的特殊欄位是對的

3. 求某乙個索引範圍內的資訊

整體思路是分治,遞迴求解。 

leetcode 307 是乙個典型的線段樹

給定乙個整數陣列  nums,求出陣列從索引 i 到 j  (i ≤ j) 範圍內元素的總和,包含 i,  j 兩點。

update(i, val) 函式可以通過將下標為 i 的數值更新為 val,從而對數列進行修改。

示例:

given nums = [1, 3, 5]

sumrange(0, 2) -> 9

update(1, 2)

sumrange(0, 2) -> 8

說明:

陣列僅可以在 update 函式下進行修改。

你可以假設 update 函式與 sumrange 函式的呼叫次數是均勻分布的。

這道題,看到題之後,最樸素的解法就是每次都從i到j遍歷,更新就直接更新。 這樣更新的時間複雜度是o1, 求和的時間複雜度是on

這個時候,思考下有沒有別的解決辦法, 我們維護乙個前n項和的陣列,sum(n) = 0 到 n的累加和, range(i,j)= sum(j) - sum(i)

這樣的話range的時間複雜度就是o1了, 但是更新的時候你需要更新很多個前n項和,這樣更新就成on了, 有沒有更優的解法呢?

用segment tree,這樣的話更新和查詢就都是logn的時間複雜度了,這樣就優了不少, 比如n等於1000, 那麼乙個o1的時間複雜度乙個on的時間複雜度那麼總共就是1000+

,但是兩個都是logn的話,就是20, 如果n比較大的話那麼差別就更大了。

talk is cheap, 上**

class

numarray

}int n;

segmenttree head;

public numarray(int

nums)

segmenttree init (

int nums, int start, int

end)

int mid = (start + end)/2;

segmenttree left =init(nums, start, mid);

segmenttree right = init(nums, mid + 1, end);

return

new segmenttree(start, end, left.sum +right.sum, left, right);

}public

void update(int i, int

val)

void runupdate(segmenttree root, int i, int

val)

int mid = (root.start + root.end)/2;

if (i <=mid)

else

root.sum = root.left.sum +root.right.sum;

}public

int sumrange(int i, int

j)

int runsumrange(segmenttree root, int i, int

j)

int mid = (root.start + root.end)/2;

if (j <=mid)

if (i >mid)

return runsumrange(root.left, i, mid) + runsumrange(root.right, mid + 1, j);

}}

資料結構 線段樹

啦啦啦啦啦啦線段樹是個好東西 好吧並沒有什麼好的 但貌似還是很好啊 線段樹就是一棵樹!顧名思義 又是這個詞 就是求關於一段的某些什麼什麼東西。比如區間最大值啊什麼的。引用百科知識 線段樹是一種二叉搜尋樹,與區間樹相似,它將乙個區間劃分成一些單元區間,每個單元區間對應線段樹中的乙個葉結點。對於線段樹中...

資料結構 線段樹

一 目標 1.如何快速的查詢出下列陣列arr 2,5 的和 2。以及更新arr 4 為6。用普通的方法查詢的複雜度為o n 更新的複雜度為o 1 這時候我們可以用線段樹來快速完成這些操作,複雜度為logn。二 內容 如何建立,查詢,更新線段樹。public class qurqpd int tree...

資料結構 線段樹

線段樹是一顆平衡的二叉搜尋樹,他以空間換區時間,讓線性查詢加速log級別的查詢,用到的演算法主要是二分搜尋和遞迴。例如 有陣列data 我有乙個需求,我需要頻繁的查詢區間i j的sum和。這裡先給出兩個解決方案 如果使用最普通的演算法遍歷,那麼查詢和更新的複雜度為o n 當然你還可以使用動態規劃,定...