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 (線段樹 區間最值)
- 區間演算法題用線段樹可以秒解?演算法
- 線段樹 區間乘法加法混合
- 數列求和【線段樹基礎】
- HDU1754 I Hate It 【線段樹基礎:點修改+區間查詢】
- HDU 2795 Billboard(線段樹 區間最大)
- 線段樹(3)——區間操作疊加
- 芻議線段樹 2 (區間修改,區間查詢)
- 線段樹維護區間等差數列
- POJ 3468 【區間修改+區間查詢 樹狀陣列 | 線段樹 | 分塊】陣列
- HDU 3397 Sequence operation(線段樹區間染色加區間合併)
- 區間k小值(可持久化線段樹)持久化
- POJ 3468 A Simple Problem with Integers (線段樹 區間共加)
- HDU1698 Just a Hook【線段樹基礎:區間修改+區間查詢】Hook
- HDU 4027 Can you answer these queries? (線段樹 區間開方)
- C++演算法 線段樹C++演算法
- POJ 2528 Mayor's posters (線段樹 區間更新+離散化)
- 【知識點】淺入線段樹與區間最值問題
- [藍橋杯][演算法提高VIP]上帝造題五分鐘 (線段樹+區間最小值)演算法
- 【Leetcode每日一題】327. 區間和的個數(線段樹/樹狀陣列)LeetCode每日一題陣列
- 線~段~樹
- 線段樹
- 演算法隨筆——主席樹(可持久化線段樹)演算法持久化
- 一些線段樹典(求求了區域賽遇到線段樹不要被卡了)
- 線段樹(1)建樹、單點修改、單點查詢、區間查詢和例題
- 線段樹模板
- 線段樹--RMQMQ
- 01 線段樹
- 線段樹 hate it
- 【模版】線段樹
- HDU1166 敵兵佈陣【線段樹基礎:點修改+區間查詢】
- 洛谷P1712 [NOI2016]區間 尺取法+線段樹+離散化
- P8868 [NOIP2022] 比賽(線段樹維護區間歷史和)
- 線段樹維護單調棧——區間查詢版本 & 維護遞減序列
- ut.cpp 最大線段並減線段交 [線段樹]
- 權值線段樹
- 線段樹筆記筆記
- Segment Tree(線段樹)
- 線段樹入門