给定一个整数数组(下标由 0 到 n-1,其中 n 表示数组的规模),以及一个查询列表。每一个查询列表有两个整数[start, end]
。
对于每个查询,计算出数组中从下标 start 到 end 之间的数的最小值,并返回在结果列表中。
样例
对于数组 [1,2,7,8,5]
, 查询 [(1,2),(0,4),(2,4)]
,返回 [2,1,5]
每次查询在O(logN)的时间内完成
/**
* Definition of Interval:
* classs Interval {
* int start, end;
* Interval(int start, int end) {
* this->start = start;
* this->end = end;
* }
*/
class Solution {
private:
struct segmentTreeNode{
int start,end,min;
segmentTreeNode* left,*right;
segmentTreeNode(int lo,int hi):start(lo),end(hi),left(0),right(0){}
};
segmentTreeNode* stBuild(int i,int j){
if(i>j) return NULL;
segmentTreeNode* root=new segmentTreeNode(i,j);
if(i==j) return root;
int mid=i+(j-i)/2;
root->left=stBuild(i,mid);
root->right=stBuild(mid+1,j);
return root;
}
void stModify(segmentTreeNode *root,int i,int val){
if(root->start==root->end){
root->min=val;
return;
}
int mid=root->start+(root->end-root->start)/2;
if(i<=mid) stModify(root->left,i,val);
else stModify(root->right,i,val);
root->min=min(root->left->min,root->right->min);
return;
}
int stQuery(segmentTreeNode *root,int start,int end){
if(start>end) return INT_MAX;
if(start==root->start&&end==root->end) return root->min;
int mid=root->start+(root->end-root->start)/2;
int ans=INT_MAX;
ans=min(ans,stQuery(root->left,start,min(end,mid)));
ans=min(ans,stQuery(root->right,max(start,mid+1),end));
return ans;
}
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
vector<int>res;
int n=A.size();
if(n==0) return res;
int m=queries.size();
if(m==0) return res;
segmentTreeNode *root=stBuild(0,n-1);
for(int i=0;i<n;i++){
stModify(root,i,A[i]);
}
for(int i=0;i<m;i++){
Interval q=queries[i];
int tmp=stQuery(root,q.start,q.end);
res.push_back(tmp);
}
return res;
}
};