206. 区间求和 I
描述
给定一个整数数组(下标由 0 到 n-1,其中 n 表示数组的规模),以及一个查询列表。每一个查询列表有两个整数 [start, end] 。 对于每个查询,计算出数组中从下标 start 到 end 之间的数的总和,并返回在结果列表中。
样例 1:
输入:
数组 = [1,2,7,8,5], 查询 = [(0,4),(1,2),(2,4)]
输出:
[23,9,20]
样例 2:
输入:
数组 = [4,3,1,2], 查询 = [(1,2),(0,2)]
输出:
[4,8]
挑战
每一次查询的时间复杂度为O(logN)
题解
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param A: An integer list
* @param queries: An query list
* @return: The result list
*/
public List<Long> intervalSum(int[] A, List<Interval> queries) {
// write your code here
SegmentTreeNode n = this.buildSum(A, 0, A.length - 1);
List<Long> ret = new ArrayList<>();
for (Interval q : queries) {
long i = this.querySum(n, q.start, q.end);
ret.add(i);
}
return ret;
}
/**
* 构造线段树
* @param A
* @param start
* @param end
* @return
*/
private SegmentTreeNode buildSum(int[] A, int start, int end) {
if (start > end) {
return null;
}
SegmentTreeNode n = new SegmentTreeNode(start, end);
if (start != end) {
int mid = (start + end) / 2;
n.left = buildSum(A, start, mid);
n.right = buildSum(A, mid + 1, end);
n.value = n.left.value + n.right.value;
} else {
n.value = A[start];
}
return n;
}
/**
* 线段树查找
* @param root
* @param start
* @param end
* @return
*/
private long querySum(SegmentTreeNode root, int start, int end) {
if (root.start == start && root.end == end) {
return root.value;
}
long leftSum = 0;
long rightSum = 0;
int mid = (root.start + root.end) / 2;
if (start <= mid) {
leftSum = querySum(root.left, start, Math.min(mid, end));
}
if (mid < end) {
rightSum = querySum(root.right, start <= mid ? ++mid : start, end);
}
return leftSum + rightSum;
}
// Definition of SegmentTreeNode:
class SegmentTreeNode {
public int start, end;
public long value;
public SegmentTreeNode left, right;
public SegmentTreeNode(int start, int end) {
this.start = start;
this.end = end;
this.left = this.right = null;
}
public SegmentTreeNode(int start, int end, long value) {
this.start = start;
this.end = end;
this.value = value;
this.left = this.right = null;
}
}
}
最后说两句
非常感谢你阅读本文章,如果你觉得本文对你有所帮助,请留下你的足迹,点个赞,留个言,多谢~
作者水平有限,如果文章内容有不准确的地方,请指正。
希望小伙伴们都能每天进步一点点。
声明
本文由二当家的白帽子博客原创,转载请注明来源,谢谢~