给定一个整数数组(下标由 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:
* classs Interval {
* int start, end;
* Interval(int start, int end) {
* this->start = start;
* this->end = end;
* }
* }
*/
class SegmentTreeNode1
{
public:
int start;
int end;
long long sum;
SegmentTreeNode1 *left, *right;
SegmentTreeNode1(int start,int end,int sum)
{
this->start=start;
this->end=end;
this->sum=sum;
this->left = this->right = NULL;
}
};
class Solution {
public:
/**
* @param A: An integer list
* @param queries: An query list
* @return: The result list
*/
vector<long long> intervalSum(vector<int> &A, vector<Interval> &queries) {
// write your code here
vector<long long>res;
if(A.size()<=0||queries.size()<=0)return res;
SegmentTreeNode1*root=build(A,0,A.size());
for (int i = 0; i < queries.size(); i++) {
res.push_back(query(root,queries[i].start,queries[i].end));
}
return res;
}
SegmentTreeNode1*build(vector<int>&A,int start,int end)
{
SegmentTreeNode1*node;
if(start!=end)
node=new SegmentTreeNode1(start,end,0);
else
node=new SegmentTreeNode1(start,end,A[start]);
if(start==end) return node;
node->left=build(A,start,(start+end)/2);
node->right=build(A,(start+end)/2+1,end);
node->sum=node->left->sum+node->right->sum;
return node;
}
long long query(SegmentTreeNode1 * root, int start, int end) {
// write your code here
int mid=(root->start+root->end)/2;
if(root->start>=start&&root->end<=end) return root->sum;
else if(start>mid)return query(root->right,start,end);
else if(end<mid+1)return query(root->left,start,end);
else return query(root->left,start,end)+query(root->right,start,end);
}
};