社区
数据结构与算法
帖子详情
请教一个算法
djj2007
2011-03-08 03:27:10
一个集合c,包含大量(>100w)对象,每个对象包含属性:int value1,int value2。每个对象的valve1和value2是一个随机数,在初始化的时候确定。
然后是非常多次的查询,对于每次给定的两个值m,n,得到集合中 value1 > m && value2 > n 的对象集。
求一个算法可以快速求解
...全文
392
15
打赏
收藏
请教一个算法
一个集合c,包含大量(>100w)对象,每个对象包含属性:int value1,int value2。每个对象的valve1和value2是一个随机数,在初始化的时候确定。 然后是非常多次的查询,对于每次给定的两个值m,n,得到集合中 value1 > m && value2 > n 的对象集。 求一个算法可以快速求解
复制链接
扫一扫
分享
举报
写回复
配置赞助广告
用AI写文章
15 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
foreverlin1204
2011-03-15
打赏
举报
回复
可以离线处理的,问题等价成求二维点坐标上一个点的支配集,离线操作的话可以用树状数组,这个常数远远小于各种平衡树,唯一不好的是这事一个离线的办法
zyl072
2011-03-13
打赏
举报
回复
[Quote=引用 13 楼 xsj_guagua 的回复:]
额,我觉得你真的误会了,对于二维的两个元素,我把它视为一个结构体,然后自定义一个比较函数,比如x,y都大的大之类的,然后转化为一维的问题。
可能你没怎么用过stl的泛型算法吧
[/Quote]
不解释。
你直接上代码吧,我给你找反例。
xsj_guagua
2011-03-13
打赏
举报
回复
[Quote=引用 10 楼 zyl072 的回复:]
引用 3 楼 xsj_guagua 的回复:
对于100w的数据,按照lz的描述,每个数据8字节,那么数据量大于16m
如果数据量在这个等级上的话,在堆中建立RBtree,或者直接用STL的set,你自己定义一个比较函数也可以做到,就是建树的消耗比较大,而且你要求的只是一个大于m,n的集合,并没要求严格排序,所以用tree有点浪费。要达到你要的集合,先中序遍历树,然后每次只要查询到你要的点……
[/Quote]
额,我觉得你真的误会了,对于二维的两个元素,我把它视为一个结构体,然后自定义一个比较函数,比如x,y都大的大之类的,然后转化为一维的问题。
可能你没怎么用过stl的泛型算法吧
修心-明
2011-03-12
打赏
举报
回复
我个人觉得分如果集合是没有排序的,用树形结构用处不是太大。
如果集合是list的,我建义使用多线程。将集合分成多段,每一个线程做一段。(记得同步结果集合)
zyl072
2011-03-11
打赏
举报
回复
[Quote=引用 6 楼 lzy18lzy 的回复:]
这个问题,可以转化为线段树问题,只不过是分为四叉了
[/Quote]
仔细思考了一下, 四叉的二维线段数可行,而且更快。 赞6楼!
zyl072
2011-03-11
打赏
举报
回复
[Quote=引用 3 楼 xsj_guagua 的回复:]
对于100w的数据,按照lz的描述,每个数据8字节,那么数据量大于16m
如果数据量在这个等级上的话,在堆中建立RBtree,或者直接用STL的set,你自己定义一个比较函数也可以做到,就是建树的消耗比较大,而且你要求的只是一个大于m,n的集合,并没要求严格排序,所以用tree有点浪费。要达到你要的集合,先中序遍历树,然后每次只要查询到你要的点就可以了 O(log2n)
这个问题你可以抽象成……
[/Quote]
请不要把解决一维问题的思路拿来解决二维的问题。
二维的问题在于,
对象之间无法进行大小比较。
举例: (2,3) 和 (3,2) 你说两个对象谁大谁小? 既无大小的概念,又谈何排序?
既然二维对象无法排序,
所有以上回帖中只要是基于有序为前提的算法都是无效的
,包括上面提到的BTree、排序二叉树等。
非得要排序,只能是严格定义 优先按X坐标排,X相等时再按Y坐标排。如此一来进行查找时,可以二分法快速定位到 X > M的位置,但仍然需要对所有的 X>M 进行一次O(N)的遍历,取出其中Y>N的对象。
但显然这是一个低效算法,每次查找的平均复杂度仍然是 O(N)。
========================分割线=====================
说下我的想法,将这些对象看成平面上的坐标点。其实就是给定 任意的(M,N), 求 (M,N) 右上角的所有点。
采用分块方法。假设有100W个点,
初始化:
将整个平面进行分块,分成 10000个块 。
具体分块方式由如下:X坐标轴平均分成100份(按X坐标扫描一遍,每隔1W个点则分出一块)。 Y坐标轴也用同样的方法分成100份。 由此,X坐标方向和Y坐标方向总共被切分成1万个块。每块平均有100个点。
对于每一个块内的元素,分别存两份,一份按X坐标排序,另一份按Y坐标排序。
查找算法
对于任意给定的(M,N) ,先用二分的方法定位出该点所在的
块
。
1.显然,该块的右上角所有块都必定是满足条件的,直接将这些块内的元素全部输出。
2.遍历一次该块内部的100个点,得到块内满足条件的点输出。
3.遍历该块右边的所有同一水平线上的块, 对每一个块的
Y坐标
排序那一份进行二分定位。然后
输出所有 Y>N的点
。
4.遍历该块上面的所有同一竖直线上的块,对每一个块的
X坐标
排序的那一份进行二分定位,然后
输出所有N>X的点
。
复杂度估计,除去输出的时间,最终用来求结果的复杂度稳定在 O( 100 * LOG(100))。
弦率
2011-03-10
打赏
举报
回复
学习了,链表能实现吗
chunjvke
2011-03-10
打赏
举报
回复
由于查询次数多,应当对两个属性建索引,
lzy18lzy
2011-03-09
打赏
举报
回复
这个问题,可以转化为线段树问题,只不过是分为四叉了
showjim
2011-03-09
打赏
举报
回复
相当于一个矩阵找一个角的所有点,4叉树应该可以用
超级大笨狼
2011-03-09
打赏
举报
回复
如果是比较大小的话,利用二叉树。
djj2007
2011-03-08
打赏
举报
回复
请问下rtree该怎么实现,好像是用于磁盘文件管理的吧
xsj_guagua
2011-03-08
打赏
举报
回复
对于100w的数据,按照lz的描述,每个数据8字节,那么数据量大于16m
如果数据量在这个等级上的话,在堆中建立RBtree,或者直接用STL的set,你自己定义一个比较函数也可以做到,就是建树的消耗比较大,而且你要求的只是一个大于m,n的集合,并没要求严格排序,所以用tree有点浪费。要达到你要的集合,先中序遍历树,然后每次只要查询到你要的点就可以了 O(log2n)
这个问题你可以抽象成在一组无序数中寻找第k大的数算法,只不过你这的比较函数要自定义一下,而你要寻找的是比k大的一个区间。
算法导论上有给出这个中位数算法,就是按照快排的划分算法,每划分一次,按照中间点的位置和你要寻找的k数字相比较,如果大,就在当前区间的左半边继续进行划分,如果小,就在当前区间的右半边进行划分,递归进行,这种单次的复杂度为O(n),当你频繁查询的时候,你可以记下上一次的查询位置,以后的每次只要在半边进行划分就可以了,虽然也是O(log2n)但是n平均情况下要比之前的小一半。
绿色夹克衫
2011-03-08
打赏
举报
回复
用类似RTree的方式做索引可以,还能实现更复杂的查询
Coolfatman
2011-03-08
打赏
举报
回复
如果查询次数少,滚几次就行了。
如果查询次数多,那么实现comparator 把对象排序,然后用2分法定位即可。
如果真的太多。把对象放进数据库,然后建索引,查询就是了。
算法
--下
一个
排列
实现获取下
一个
排列的函数,
算法
需要将给定数字序列重新排列成字典序中下
一个
更大的排列。 如果不存在下
一个
更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1 看一下代码: func nextPermutation(nums []int) ...
算法
题 下
一个
排列
本文介绍了如何实现获取下
一个
排列的
算法
。给定
一个
整数序列,该
算法
将其重新排列成字典序中下
一个
更大的排列,若已是最大排列则返回最小排列。
算法
核心步骤为:1)从后向前找第
一个
降序位置;2)在右侧找第
一个
大于该位置的数并交换;3)反转右侧子数组使其升序。时间复杂度O(n),空间复杂度O(1)。关键点在于定位需要交换的位置并通过反转右侧保证最小增量。文章提供了详细
算法
思路、Java实现代码、过程示例和常见问题解答,帮助理解这一排列生成问题。
【
算法
】下
一个
排列
给定
一个
整数序列,下
一个
排列是指比当前序列字典序上大且最小的排列。例如,序列[1,2,3]的下
一个
排列是[1,3,2]。本文通过深入探讨“下
一个
排列”
算法
,不仅揭示了C++在
算法
实现上的强大与灵活性,也展示了该
算法
在不同领域的广泛应用潜力。掌握此类
算法
不仅能够提升解决特定问题的能力,更能深化对数据结构和
算法
原理的理解。未来,随着
算法
技术的不断进步和应用场景的拓展,诸如“下
一个
排列”这样的
算法
将持续在数据分析、竞赛编程等领域发挥重要作用,推动技术边界不断向前。
算法
——下
一个
排列
实现获取下
一个
排列的函数,
算法
需要将给定数字序列重新排列成字典序中下
一个
更大的排列。 如果不存在下
一个
更大的排列,则将数字重新排列成最小的排列(即升序排列)。 必须原地修改,只允许使用额外常数空间。 链接: leetcode. 解题思路:从后往前遍历,检测到第
一个
如果前一元素小于当前元素,那就说明下一排列就需要替换前一元素,因为该元素之后的序列是
一个
递减的排列,然后从这个前一元素开始向后遍历,直到遍历到第
一个
比这个元素小的元素,如果都比这个元素大,就取最后的元素,然后与之替换,再然后,反转这个前一元素之.
国央企如何运用数据分析实现数字化转型?.docx
国央企如何运用数据分析实现数字化转型?
数据结构与算法
33,025
社区成员
35,334
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章