Java 演算法-區間求和I(線段樹)
我之前學過線段樹,掌握的不是很牢固,而這道題是線段樹,為了加深記憶,所以還是覺得有必要記錄下來,就當是對線段樹的一個複習。
題意:
給定一個整數陣列(下標由 0 到 n-1,其中 n 表示陣列的規模),以及一個查
詢列表。每一個查詢列表有兩個整數 [start, end] 。 對於每個查詢,計算出數
組中從下標 start 到 end 之間的數的總和,並返回在結果列表中。
樣例:
對於陣列 [1,2,7,8,5],查詢[(1,2),(0,4),(2,4)], 返回 [9,23,20]
1.解題思路
這道題用線段樹數做起來不是很難,同時時間複雜度也不是很高。由於樓主之前學過線段樹,所以這裡不再詳細的講解什麼是線段樹。
我們在構建線段樹時,向線段樹的每一個節點加一個屬性--sum,用來表示當前節點的範圍的數值總和。然後在使用線段樹的查詢就可以得到我們想要的值了。
(1).構建線段樹
private SegmentTreeNode build(int A[], int start ,int end) {
SegmentTreeNode node = new SegmentTreeNode(start, end, A[0]);
if(node.start == node.end) {
node.sum = A[start];
return node;
}
int mid = (node.start + node.end) / 2;
node.left = build(A, start, mid);
node.right = build(A, mid + 1, end);
node.sum = node.left.sum + node.right.sum;
return node;
}
(2).查詢線段樹
private long query(SegmentTreeNode node, int start , int end) {
if(start > end) {
return 0;
}
if(node.start == start && node.end == end) {
return node.sum;
}
int mid = (node.start + node.end) / 2;
if(end <= mid) {
return query(node.left, start, end);
}
else if(start > mid) {
return query(node.right, start, end);
}else {
return query(node.left, start, mid) + query(node.right, mid + 1, end);
}
}
2.程式碼
public List<Long> intervalSum(int[] A, List<Interval> queries) {
List<Long> list = new ArrayList<>();
if(A.length == 0 || queries.size() == 0) {
return list;
}
SegmentTreeNode node = build(A, 0, A.length - 1);
for(int i = 0; i < queries.size(); i++) {
list.add(query(node, queries.get(i).start, queries.get(i).end));
}
return list;
}
//構建線段樹
private SegmentTreeNode build(int A[], int start ,int end) {
SegmentTreeNode node = new SegmentTreeNode(start, end, A[0]);
if(node.start == node.end) {
node.sum = A[start];
return node;
}
int mid = (node.start + node.end) / 2;
node.left = build(A, start, mid);
node.right = build(A, mid + 1, end);
node.sum = node.left.sum + node.right.sum;
return node;
}
//查詢線段樹
private long query(SegmentTreeNode node, int start , int end) {
if(start > end) {
return 0;
}
if(node.start == start && node.end == end) {
return node.sum;
}
int mid = (node.start + node.end) / 2;
if(end <= mid) {
return query(node.left, start, mid);
}
else if(start > mid) {
return query(node.right, start, end);
}else {
return query(node.left, start, mid) + query(node.right, mid + 1, end);
}
}
相關文章
- HDU 1754 I Hate It (線段樹 區間最值)
- hihocoder 1078 線段樹的區間修改 (線段樹 區間更新 模板)
- 區間演算法題用線段樹可以秒解?演算法
- 數列求和【線段樹基礎】
- 線段樹(3)——區間操作疊加
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- 芻議線段樹 2 (區間修改,區間查詢)
- 線段樹維護區間等差數列
- hdu 1754 I Hate It (線段樹)
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- POJ 3468 A Simple Problem with Integers(線段樹區間操作)
- HDU 1698 Just a Hook (線段樹區間更新)Hook
- POJ 3468 A Simple Problem with Integers (線段樹 區間更新)
- Codeforces 52C (線段樹區間更新)
- 區間k小值(可持久化線段樹)持久化
- hdu 1754 【線段樹/RMQ】I Hate ItMQ
- hdu 2665 可持久化線段樹求區間第K大值(函式式線段樹||主席樹)持久化函式
- POJ 3468 A Simple Problem with Integers (線段樹 區間共加)
- POJ 3468-A Simple Problem with Integers(區間更新線段樹)
- HDU 1754 I Hate It 線段樹入門
- D 區間求和 [數學 樹狀陣列]陣列
- 1082 線段樹練習 3 區間查詢與區間修改
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- C++演算法 線段樹C++演算法
- 演算法:區間樹演算法
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- POJ 2528 Mayor's posters (線段樹區間更新 + 離散化)
- Codeforces 272C Dima and Staircase (線段樹區間更新 或 線性掃)AI
- 線~段~樹
- 線段樹
- POJ 2777-Count Color(線段樹-區間染色查詢)
- 【知識點】淺入線段樹與區間最值問題
- [藍橋杯][演算法提高VIP]上帝造題五分鐘 (線段樹+區間最小值)演算法
- (hdu 1754) I Hate It(線段樹基礎,單點更新)
- 演算法隨筆——主席樹(可持久化線段樹)演算法持久化
- 一些線段樹典(求求了區域賽遇到線段樹不要被卡了)
- 1080 線段樹練習 單點修改及區間查詢
- POJ 3264-Balanced Lineup詳解(線段樹區間求值)