社区
数据结构与算法
帖子详情
一个很简单的问题,却没有想出一个好的解法
绿色夹克衫
2010-08-07 04:32:59
集合A包含n个正整数,其中最大的数为m。集合B是从A中任选2个元素相加去掉重复后所组成的集合。
有没有什么快速的方法求集合B?难道只能是n^2?有没有复杂度是关于m的方法?
用线段树也许可以好一点,不过只是我想的土方法,听听大家说的吧!
...全文
1508
41
打赏
收藏
一个很简单的问题,却没有想出一个好的解法
集合A包含n个正整数,其中最大的数为m。集合B是从A中任选2个元素相加去掉重复后所组成的集合。 有没有什么快速的方法求集合B?难道只能是n^2?有没有复杂度是关于m的方法? 用线段树也许可以好一点,不过只是我想的土方法,听听大家说的吧!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
41 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
菠萝先生
2010-09-10
打赏
举报
回复
你们这些疯子!!!!!!!!强烈鄙视!
chenchangxiong
2010-09-08
打赏
举报
回复
汗 发错了
chenchangxiong
2010-09-08
打赏
举报
回复
咋可能是klogk
光为了找到这个数,在最糟情况下要计算的加法就要k(k+1)/2次
这是因为
a[x] + b[y] 并不一定比 a[x-i] + b[y+j]要来的大,反之亦然
个人认为复杂度应当为k2logk
因为对斜上矩阵,从左到右推,每列据对角线为i的数的最大比较为log(i+1)
每列复杂度为ilogi
最后复杂度为k2logk
huangying1201
2010-09-08
打赏
举报
回复
提供一个算法,大家看看可不可行:
举例a ={8 ,6, 1 }
b= {7,4,3,2}
可以构成求和距阵(这里只是便于表示,并不需要在内存中建立该距阵方正大小为max{m,n},行或列不够的在末尾补充0或最小值)
8 6 1 0
7 15 13 8 0
4 12 10 5 0
3 11 9 4 0
2 10 8 3 0
由这个方阵规律可以观察到(i为行标,j为列标):
1. 最大的1个:15((i=1&&j<=1)||(j=1&&i<=1))
2. 最大的[2,4]个:13, 12 10((i=2&&j<=2)||(j=2&&i<=2))
3. 最大的[5,9]个:8,5,4,9,11((i=3&&j<=3)||(j=3&&i<=3))
令S(0)=1,s(n)=n*n-s(n-1)-s(n-2)-...-s(1)(注:n=i*i)可以求得S(n)用n来表示的表达式
对于任意i=t,
最大的[t*t-s(t),t*t]个:一定满足((i=t&&j<=t)||(j=t&&i<=t))
所以要求第k大的,可以由k求得t使得k属于区间[[t*t-s(t),t*t]] 复杂度O(1)
只需要求((i=t&&j<=t)||(j=t&&i<=t))区间间第k-(S(t-1)+S(t-2)+S(t-3)...+S(1))大的数目复杂度O(t)
区间数据数目为2*t-1(大大小于m*n).此时可以采用楼上的算法求得
算法复杂度小于O(K)
超级大笨狼
2010-08-11
打赏
举报
回复
FancyMouse
集合B是从A中任选2个元素相加去掉重复后所组成的集合
去掉重复后所组成的集合
去掉重复
你不查,怎么去掉?
让我说你啥好呢?
绿色夹克衫
2010-08-09
打赏
举报
回复
这是一个查找的复杂度吧,并没有包括生成数据部分
[Quote=引用 33 楼 superdullwolf 的回复:]
最小n,最大10n的话
那就在[n,10n]内做桶,要存放n个数字,每个桶大小最多是9,就是需要最多4层的二叉就可以装下。
4层的二叉1+2+4+8=15
桶的数量是(10n-n)/15个=9n/15=3n/5个。
这样复杂度大概是O(4层×桶数3n/5)=O(12/5n)=O(2.4 * n)=O(C*n)
[/Quote]
超级大笨狼
2010-08-09
打赏
举报
回复
最小n,最大10n的话
那就在[n,10n]内做桶,要存放n个数字,每个桶大小最多是9,就是需要最多4层的二叉就可以装下。
4层的二叉1+2+4+8=15
桶的数量是(10n-n)/15个=9n/15=3n/5个。
这样复杂度大概是O(4层×桶数3n/5)=O(12/5n)=O(2.4 * n)=O(C*n)
perfecttt
2010-08-08
打赏
举报
回复
上面的计算有点错误,最后的那个n*logn有问题,肯定是小于等于n*logn的。
FancyMouse
2010-08-08
打赏
举报
回复
>在根,左,右这样两层的容器里查存在,我们可以认为是O(1)=C,C是层数,就算十层,也是常数的,秒杀。
完全不知所云。查存在,查什么的存在?
perfecttt
2010-08-08
打赏
举报
回复
对A集合做一个排序,然后将重复的去除,比如 A = {1,2,3,3,3,4,4,5},去除重复的就是A={1,2,3,4,5}
O(n)
那B集合就是 B = {1+2,1+3,1+4,2+3,1+5,2+4,2+5,3+4,3+5,4+5}={3,4,5,5,6,6,7,7,8,9}
O(n*logn)
最后是B={3,4,5,6,7,8,9}
n = 8; m = 5; 最后算法复杂度是 n+nlogn+x;最后复杂度是 n*logn ,好像和m没什么太大的关系,就算有m级别的算法,肯定也不准~
michael122
2010-08-08
打赏
举报
回复
学习了
绿色夹克衫
2010-08-08
打赏
举报
回复
嗯,也研究一下笨狼兄的思路。可以认为m > n,m < 10 * n,细说一下桶怎么处理!
或者以20以内的奇数为例吧!
超级大笨狼
2010-08-08
打赏
举报
回复
换句话来说,离散情况如果提前知道,那么我们完全可以规划出不一样大小的桶。
如果数据恰好是按照均匀分布的,那么做均匀的桶没问题。
如果数据是接近指数分布的,我们把数据排序O(n*lgn)
后分成k份,每份做大小不一致的桶,这样还是可以接近C*n+n*lgn=n*lgn复杂度的.
问题的关键还是桶怎么做的问题,是概率问题。
超级大笨狼
2010-08-08
打赏
举报
回复
如果离散情况分布是均匀的,类似,A = {1,3,5,7,9,11} B应该是{2,4,6,8,10,12,14,16,18,20,22}
就可以O(C*n)
如果A = {1,3,5,7,9,110000000}跨度巨大。
B应该是{2,4,6,。。。。,220000000}
那容积率过大,做桶的办法就接近最坏的情况了,最坏复杂度n*∑2^C=n*(2M-2m)/n=n^2
就是2M-2m>n^2的情况是个死界限,超过这个就是被鄙视的。
所以,我的结论:
2M-2m<n^2的情况下,复杂度可以是O(C*n)的。
至于楼上几个同学n*logn的算法,我没仔细研究,基于平时对这几位同学的了解,他们肯定是厉害的。
不过和O(n*logn)比较,要想证明其适用界限,同理
2M-2m<n*logn的情况下,复杂度可以是O(C*n)的。
如果满足上面的条件,就可以用我罗嗦的O(C*n)算法。
超级大笨狼
2010-08-08
打赏
举报
回复
集合A包含n个正整数,其中最大的数为m。
这个和分布情况也有关系。
B中最大的是2*Max(A)取名叫xxxx,最小的是2*Min(A)取名叫xx
那么在[xx,xxxx]内牺牲空间做桶的话,如果桶数小于n^2,就是一个小于n^2的算法。
至于做桶,还是要看分布情况。比如可以规划∑2^n个数字一桶
(桶里用二叉或者最大/小堆之类的存储,便于检索,所以是∑2^n,
因为二叉每层是1,2,4,8个,那么桶大小就可能是1,3,7,15。。。)
桶内数字越大,需要空间越小,但是复杂度会稍微受影响。
比如:
A = {1,3,5,7,9,11} B应该是{2,4,6,8,10,12,14,16,18,20,22}
可以在O(n)内同时找到最大最小值2和22
那么规划一个2到22的桶,每个桶咱放3个数字(根,左,右),那么需要22-2/3=20/3=7个桶。
在根,左,右这样两层的容器里查存在,我们可以认为是O(1)=C,C是层数,就算十层,也是常数的,秒杀。
不过层数多会牺牲空间,可以根据实际分布情况来决定。
这样就是得到了一个O(C*n)的算法。复杂度大小取决与层数的设计。
而层数的设计就和你的"其中最大的数为M"和"其中最小的数为m"有关系。
集合A包含n个正整数,其中最大的数为M,最小的数为m。
(2M-2m)/n为容积率μ ,在∑2^n就是1,3,7,15。。。中选择一个数字恰好放下该容积率的数字,就是解题的关键。假设μ =4,那么选7比较合适;假设μ =8,那么选15比较合适;层数C=1+log(μ)取上整ceiling
所以我认为,复杂度是O(C*n)的。
FancyMouse
2010-08-08
打赏
举报
回复
mlogm的FFT那是标准的FFT习题。去年学校算法课还考到这题结果基本崩掉全班。
绿色夹克衫
2010-08-07
打赏
举报
回复
再说一下那个帖子里的问题,大概就是说,有2000个整数,从中选3000个,使他们的和是100000,可以重复选。
直接DP的话空间要求太高了。时间也比较慢。
这个问题搞定了的话,应该可以有100000 * log(100000) * lg(3000)的解法,并且空间为100000 * log(3000)
绿色夹克衫
2010-08-07
打赏
举报
回复
嘿嘿,模型转化之后大家就都明白了。其实是今天看一个哥们的需求,想到这个问题的。
就是一个背包程序。但弄不好要开很大的空间才能解。有了这个方法,就简单多了。
http://topic.csdn.net/u/20100807/09/18a5d6a7-5201-4251-bcef-7d2b5009dc42.html
[Quote=引用 21 楼 fanster28_ 的回复:]
哎呀 就是生成函数
a1 a2 ...am都是不超过m的
( .. x^a1 + ... x^am .. ) ^ 2
所以减去了最小数
展开就是靠的fft,浮点运算加高常数,理论复杂度低,实际的话我就不敢说了
当m很大的时候有用
[/Quote]
fanster28_
2010-08-07
打赏
举报
回复
哎呀 就是生成函数
a1 a2 ...am都是不超过m的
( .. x^a1 + ... x^am .. ) ^ 2
所以减去了最小数
展开就是靠的fft,浮点运算加高常数,理论复杂度低,实际的话我就不敢说了
当m很大的时候有用
绿色夹克衫
2010-08-07
打赏
举报
回复
嗯,确实是这个思路,豁然开朗了,一直感觉得靠分治,看来还真是,嘿嘿。
对FFT理解还是不深呀,学习了!sbwwkmyd同志等着接分吧!
参与讨论的几个都有份,明天再加100分。
[Quote=引用 19 楼 sbwwkmyd 的回复:]
引用 15 楼 sbwwkmyd 的回复:
设最小数为min,最大数为max,对于max-min=x,有大约x*log(x)的算法,即不带进位的大数平方算法FFT可以解决,不过FFT算法的常数项比较高。
比如:{1,3,5,7,8,9,11}
减去最小数x=1,得集合{0,2,4,6,7,8,10}
化二进制为0000010111010101
FFT平方后得0 0 0 0 0 0 ……
[/Quote]
加载更多回复(19)
报童
问题
的
简单
解法
本文提供了
一个
比传统
解法
更
简单
的报童
问题
解决方案。通过期望收益最大化,推导出最优采购量 x 的公式,涉及随机变量 D 的概率分布、累积分布函数以及临界分位数的概念。
指派
问题
匈牙利
解法
以及其优化
本文介绍了解决指派
问题
的经典方法——匈牙利
解法
,并对其进行了优化,通过实例详细展示了算法的具体步骤和应用效果。
数据结构与算法——9. 找零
问题
的递归
解法
和动态规划
解法
本文围绕找零
问题
,介绍了递归和动态规划
解法
。先阐述分治策略与递归算法关系,指出贪心策略在找零
问题
可能失效。递归
解法
能给出最优解,但重复计算多,可通过记录中间结果改进。动态规划从
简单
找零开始递推,还可扩展得到硬币组合。
约瑟夫环
问题
(
简单
解法
和递归
解法
)(python)
本文介绍约瑟夫环
问题
的多种
解法
,包括使用列表和双向队列的
简单
解法
,以及采用递归思想的高效
解法
,并详细解释了每种方法的实现原理。
约瑟夫
问题
的
解法
集锦
本文详细介绍了约瑟夫
问题
的多种版本,包括历史背景和不同情境下的
问题
描述。接着,文章探讨了解决约瑟夫
问题
的三种方法:数组
解法
、循环链表
解法
和递推
解法
,提供了相应的程序示例,帮助读者理解算法的实现过程。
数据结构与算法
33,026
社区成员
35,336
社区内容
发帖
与我相关
我的任务
数据结构与算法
数据结构与算法相关内容讨论专区
复制链接
扫一扫
分享
社区描述
数据结构与算法相关内容讨论专区
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章