区间求和

给定一个整数数组(下标由 0 到 n-1,其中 n 表示数组的规模),以及一个查询列表。每一个查询列表有两个整数[start, end] 。 对于每个查询,计算出数组中从下标 start 到 end 之间的数的总和,并返回在结果列表中。

样例 

对于数组 [1,2,7,8,5],查询[(1,2),(0,4),(2,4)], 返回 [9,23,20]

这道题和上一篇文章:利用线段树解决区间最小值问题,非常相似,只是线段树中的区间最小值min改为区间的和val。仅在求和函数getsum和查询函数query发生了变化。

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 */
class Solution {
    struct segmentTreeNode{
        int start,end;
        long  long val;
        segmentTreeNode *left,*right;
        segmentTreeNode(int l,int r):
        start(l),end(r),left(0),right(0){}
    };
    segmentTreeNode* build(int lo,int hi){
        if(lo>hi) return NULL;
        segmentTreeNode* root=new segmentTreeNode(lo,hi);
        if(lo==hi) return root;
        int mid=lo+(hi-lo)/2;
        root->left=build(lo,mid);
        root->right=build(mid+1,hi);
        return root;
    }
    void getsum(segmentTreeNode *root,int i,int value){
        if(root->start==root->end){
            root->val=value;
            return;
        }
        int mid=root->start+(root->end-root->start)/2;
        if(i<=mid) getsum(root->left,i,value);
        else getsum(root->right,i,value);
        root->val=root->left->val+root->right->val;
        return;
    }
    long long query(segmentTreeNode*root,int low,int high){
        if(low>high) return 0;
        if(low==root->start&&high==root->end){
            return (long long)root->val;
        }
        int mid=root->start+(root->end-root->start)/2;
        long long res=query(root->left,low,min(mid,high))+query(root->right,max(low,mid+1),high);
        return res;
        
    }
public:
    /**
     *@param A, queries: Given an integer array and an query list
     *@return: The result list
     */
    
    vector<long long> intervalSum(vector<int> &A, vector<Interval> &queries) {
        // write your code here
        int n=A.size(),m=queries.size();
        vector<long long>res;
        if(n==0||m==0) return res;
        segmentTreeNode*root=build(0,n-1);
        for(int i=0;i<n;i++) getsum(root,i,A[i]);
        for(int i=0;i<m;i++){
            Interval q=queries[i];
            long long tmp=query(root,q.start,q.end);
            res.push_back(tmp);
        }
        return res;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值