Lintcode---线段树查询(区间最大值)
对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max
,值为该节点所代表的数组区间start到end内的最大值。
为SegmentTree设计一个 query
的方法,接受3个参数root
, start
和end
,线段树root所代表的数组中子区间[start, end]内的最大值。
注意事项
在做此题之前,请先完成 线段树构造 这道题目。
样例
对于数组 [1, 4, 2, 3]
, 对应的线段树为:
[0, 3, max=4]
/ \
[0,1,max=4] [2,3,max=3]
/ \ / \
[0,0,max=1] [1,1,max=4] [2,2,max=2], [3,3,max=3]
query(root, 1, 1), return 4
query(root, 1, 2), return 4
query(root, 2, 3), return 3
query(root, 0, 2), return 4
思路:当遇到一些关于对连续点的修改和统计的问题时,可以考虑用线段树来解决。
这属于典型的RMQ问题(区间最值查询问题),所以最好通过构建线段树,利用线段树的性质来求解,这样将问题转化成线段树,会让复杂度降低到log(n);
还是要用递归的思路解决。先写出基准情形,然后递归解决。思路和上一篇博客求解给定区间元素个数一模一样。
都是借助于线段树本身的性质,减小算法的时间复杂度。
/** * Definition of SegmentTreeNode: * class SegmentTreeNode { * public: * int start, end, max; * SegmentTreeNode *left, *right; * SegmentTreeNode(int start, int end, int max) { * this->start = start; * this->end = end; * this->max = max; * this->left = this->right = NULL; * } * } */ class Solution { public: /** *@param root, start, end: The root of segment tree and * an segment / interval *@return: The maximum number in the interval [start, end] */ /* 思路:当遇到一些关于对连续点的修改和统计的问题时,可以考虑用线段树来解决。 这属于典型的RMQ问题(区间最值查询问题),所以最好通过构建线段树,利用线段树的性质来求解!! 这样将问题转化成线段树,会让复杂度降低到log(n); 还是要用递归的思路解决。先写出基准情形,然后递归解决。 */ int query(SegmentTreeNode *root, int start, int end) { // write your code here if(!root||start>end){ return 0; } if(root->start>=start&&root->end<=end){ return root->max; } int mid=root->start+(root->end-root->start)/2; if(start>mid){ return query(root->right,start,end); } else if(end<mid){ return query(root->left,start,end); } else return max(query(root->left,start,mid),query(root->right,mid+1,end)); } };