之前一直聽說線段樹是乙個很高階很難的資料結構,今天簡單了解了下, 感覺就是二叉樹加幾個全域性變數啊,原來這麼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, 上**
classnumarray
}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 當然你還可以使用動態規劃,定...