lintcode-205-区间最小数

205-区间最小数

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

注意事项

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

样例

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

挑战

每次查询在O(logN)的时间内完成

标签

二分法 LintCode 版权所有 线段树

思路

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

code

/**
 * Definition of Interval:
 * class Interval{
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 * };
 */
class Solution { 
public:
    /**
     *@param A, queries: Given an integer array and an query list
     *@return: The result list
     */
    vector<int> intervalMinNumber(vector<int> &A, vector<Interval> &queries) {
        // write your code here
        if (A.empty() || queries.empty()) {
            return vector<int>();
        }

        vector<int> result;
        SegmentTreeNode * 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;
    }

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

    int query(SegmentTreeNode *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->max;
        }
        else if (mid < start) {
            return query(root->right, start, end);
        }
        else if (mid + 1 > end) {
            return query(root->left, start, end);
        }
        else {
            return min(query(root->left, start, mid), query(root->right, mid + 1, end));
        }
    }
};
posted @ 2017-08-08 12:14  LiBaoquan  阅读(501)  评论(0编辑  收藏  举报