lintcode-206-区间求和 I

206-区间求和 I

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

注意事项

在做此题前,建议先完成以下三题:线段树的构造, 线段树的查询,以及线段树的修改。

样例

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

挑战

O(logN) time for each query

标签

二分法 LintCode 版权所有 线段树

思路

这里需要用上 lintcode-201-线段树的构造lintcode-202-线段树的查询,不过需要注意的是,这里求得是最小值,所以需要将线段树代码略作修改,原先 SegmentTreeNode 类中的 max 修改为 sum 变量,表示的是在区间 [start, end] 的最元素之和

code

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 */

class SegmentTreeNode2 {
public:
    int start, end;
    long long sum;
    SegmentTreeNode2 *left, *right;
    SegmentTreeNode2(int start, int end, long long sum) {
        this->start = start;
        this->end = end;
        this->sum = sum;
        this->left = this->right = NULL;
    }
};

class Solution {
public:
    /*
     * @param A: An integer array.
     * @param queries: A query list.
     * @return: The result list.
     */
    vector<long long> intervalSum(vector<int> &A, vector<Interval> &queries) {
        // write your code here
        if (A.empty() || queries.empty()) {
            return vector<long long>();
        }

        vector<long long> result;
        SegmentTreeNode2 * root = build(0, A.size() - 1, A);
        for (int i = 0; i < queries.size(); i++) {
            result.push_back(query(root, queries[i].start, queries[i].end));
        }
        return result;
    }

    SegmentTreeNode2 * build(int start, int end, vector<int> &nums) {
        // write your code here
        if (start > end) {
            return nullptr;
        }
        SegmentTreeNode2 *root = new SegmentTreeNode2(start, end, 0);
        if (start != end) {
            root->left = build(start, (start + end) / 2, nums);
            root->right = build((start + end) / 2 + 1, end, nums);
            root->sum = root->left->sum + root->right->sum;
        }
        else {
            root->sum = nums[start];
        }
        return root;
    }

    long long  query(SegmentTreeNode2 *root, int start, int end) {
        // write your code here
        int mid = (root->start + root->end) / 2;
        if (start <= root->start && end >= root->end) {
            return root->sum;
        }
        else if (mid < start) {
            return query(root->right, start, end);
        }
        else if (mid + 1 > end) {
            return query(root->left, start, end);
        }
        else {
            return query(root->left, start, mid) + query(root->right, mid + 1, end);
        }
    }
};
posted @ 2017-08-08 12:42  LiBaoquan  阅读(335)  评论(0编辑  收藏  举报