博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
区间最值查询问题
阅读量:7101 次
发布时间:2019-06-28

本文共 2510 字,大约阅读时间需要 8 分钟。

基本思想:

  该问题要求我们以较低的时间复杂度查询一段区间中的最值。最暴力的解法是将所有可能的区间序列化作为一个哈希表的键进行存储,值为区间内的最值,这样预处理的时间复杂度为O(n2),查询时间复杂度为O(1)。但这样不适用于对数组元素进行更新的操作,和getRangeSum的问题一样,这样子它的更新效率非常慢,对某个元素进行更新都要对所有包含该元素的区间进行更新,效率非常低下。这种情况下我们可以用线段树来解决。以查询最大值为例,线段树节点包含起始点和结束点以及区间内的最大值。递归调用build函数以二分的方式建立线段树,每当要更新元素时从根节点到叶子节点更新maximal,查询区间如果完全在当前节点左侧或右侧则循环,如果跨越中间位置则递归调用query函数,这种数据结构的更新和查询时间复杂度均为O(logn)。

1 struct SegmentTreeNode{ 2     SegmentTreeNode *left,*right; 3     int start,end; 4     int maximal; 5     SegmentTreeNode(int s,int e,int m):start(s),end(e),maximal(m){} 6 }; 7  8 class SegmentTree{ 9 public:10     SegmentTree(vector
nums){11 root = build(nums,0,nums.size()-1);12 }13 SegmentTreeNode *getRoot(){14 return root;15 }16 private:17 SegmentTreeNode* build(vector
&nums,int start,int end){18 if(start == end)19 return new SegmentTreeNode(start,end,nums[start]);20 SegmentTreeNode *left = build(nums,start,start+(end-start)/2);21 SegmentTreeNode *right = build(nums,start+(end-start)/2+1,end);22 SegmentTreeNode *r = new SegmentTreeNode(start,end,max(left->maximal,right->maximal));23 r->left = left;24 r->right = right;25 return r;26 }27 SegmentTreeNode *root;28 };29 30 class Solution{31 public:32 Solution(vector
&nums):tree(nums){33 34 }35 void update(int index,int val){36 SegmentTreeNode *current = tree.getRoot();37 while(current->start != current->end){38 current->maximal = max(current->maximal,val);39 if(index > current->start+(current->end-current->start)/2)40 current = current->right;41 else42 current = current->left;43 }44 current->maximal = max(current->maximal,val);45 }46 int query(int begin,int end){47 SegmentTreeNode *current = tree.getRoot();48 while(begin != current->start || end != current->end){49 if(begin > current->start+(current->end-current->start)/2)50 current = current->right;51 else if(end <= current->start+(current->end-current->start)/2)52 current = current->left;53 else54 return max(query(begin,begin+(end-begin)/2),query(begin+(end-begin)/2+1,end));55 }56 return current->maximal;57 }58 private:59 SegmentTree tree;60 };

 

转载于:https://www.cnblogs.com/haoweizh/p/10275068.html

你可能感兴趣的文章
android4.0 的图库Gallery2代码分析(三) 之Applition的初始化准备
查看>>
SOM自组织映射网络 教程
查看>>
lintcode:寻找旋转排序数组中的最小值 II
查看>>
树莓派学习笔记——交叉编译练习之SQLite3安装
查看>>
android stuido build 慢的解决办法
查看>>
Appium移动自动化测试(四)--one demo
查看>>
nginx配置location总结及rewrite规则写法
查看>>
python 登陆接口
查看>>
RedHat7 部署ELK日志分析系统
查看>>
DS实验题 Missile
查看>>
微信上 网页图片点击全屏放大
查看>>
jquery获取css颜色值返回RGB应用
查看>>
(void __user *)arg 中__user的作用
查看>>
Redefine:Change in the Changing World
查看>>
POJ 3436 ACM Computer Factory 最大流
查看>>
atitit。全局变量的设计与实现 java php的异同
查看>>
自己定义控件-画板,橡皮擦,刮刮乐
查看>>
spark 按照key 分组 然后统计每个key对应的最大、最小、平均值思路——使用groupby,或者reduceby...
查看>>
顺序表示的线性表——顺序表
查看>>
categorys源码
查看>>