一个数组的算法问题

michael122 2010-06-25 02:36:01
鉴于算法版人气不旺, 把C++版的一个算法问题转过来,看看有没有好的解决办法
原帖地址:
http://topic.csdn.net/u/20100623/09/dd25166f-bac4-4b2d-98ab-71cab69f4241.html?54216

问题描述:一个长度为2n的(整型)数组元素为 a1 a2 ... an b1 b2 ... bn
要求: 用O(1)的空间代价, 在O(n)时间内把数组变成 a1 b1 a2 b2 a3 b3 ... an bn

该贴中给出的方法很巧妙,但是还是没有满足O(1)空间的限制,或者是对数组的元素有限制才做到(相当于做hash之类的操作把原数组的数据给变换了)。如果数据不是整型的,而是任意的对象,就做不了了。

现在问: 有没有一种方法,可以只通过移动元素,来达到时间O(n) 空间(1)的要求?
...全文
1830 点赞 收藏 50
写回复
50 条回复
XDFWEF 2010年08月15日
还能标记不?试下!
回复 点赞
xupeihuagudulei 2010年07月05日
郁闷,看不懂。
回复 点赞
hslinux 2010年07月03日
[Quote=引用 42 楼 natalya13 的回复:]

Java code


public static void test(int[] arr, int size) {
int temp = arr[size / 2];
for (int i = size / 2; i != 1;) {
arr[i] = arr[(i + (i % 2) * (size - 1)) / 2];
……
[/Quote]

这个只能实现有序数组的置换,无需的就OVER了,显然不符合题意。
回复 点赞
在路上20130607 2010年07月02日
不懂算法的过来看看····
回复 点赞
ly88127959 2010年07月02日
友情帮顶~~~~!
回复 点赞
pclizheng 2010年06月30日
XUEXUEXUEE
回复 点赞
zzsskk1314ii 2010年06月29日
不是为了接分是学习学习
回复 点赞
高亮 2010年06月29日


public static void test(int[] arr, int size) {
int temp = arr[size / 2];
for (int i = size / 2; i != 1;) {
arr[i] = arr[(i + (i % 2) * (size - 1)) / 2];
// 奇数加(数组长度-1)除以2 偶数直接除以2
i = (i + (i % 2) * (size - 1)) / 2;
}
arr[1] = temp;
}





run:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, 19]
成功生成(总时间:0 秒)


时间复杂度为O(N),空间复杂度为O(2)

如果变量i用参数size代替使用。原size参数用arr.length代替,可以满足空间复杂度为O(1)

也就是说,变量i用参数size代替,就能实现空间复杂度为O(1),参数size的值再用数组对你算。java可以,C++不行。

其实实现过程简单,就是把一个要移动的位置保存好(空间复杂度O(1)),然后就开始循环移动数组中的元素,移动完再把保存的元素放的合适的位置,正好完成。
回复 点赞
cherryway 2010年06月28日
我觉得这个算法的关键是如何把移动的标签同步问题解决。只要这个问题解决了,算法就简单了啦!
回复 点赞
FancyMouse 2010年06月27日
乃说的是他的还是偶的?偶那个的话2是mod 2n-1的原根这个条件已经隐含了2n-1一定是质数幂次的条件了。2是原根这个条件只能拉掉一个固定比例的质数,最终的密度还是要比3^k-1大很多
回复 点赞
michael122 2010年06月27日
恩,这个结论应该是对的
有没有好的办法找n,使得2是2n-1的原根?
回复 点赞
FancyMouse 2010年06月27日
33L回帖写错了,是2n-1是质数。之前说的是对的,2是mod 2n-1原根的情况。

今天白天一大堆事结果33L和34L把n和2n-1混淆起来了。那两个回帖别去看。俺想说的就是2n-1如果是质数而且2是mod 2n-1原根那就一个置换。如果m=2n-1是质数>1幂次的话那(Z/mZ)*并不是{1,2,...,m-1},所以还需要考虑{p,2p,...}这个半群,等等。一般的,如果m是个合数的话那对于m的每一个因子d,{d,2d,...}都是要兜一遍的。
回复 点赞
michael122 2010年06月27日
n为素数好像也不行,用程序试了一下

[Quote=引用 33 楼 fancymouse 的回复:]

>2是2n-1的原根不能保证一个轮换就搞定吧?
这个当n是质数的时候能保证。那样的话题意所需的置换就(1 2 4 8 ...)这一个

不过p^k的时候p的确是问题……俺一直在(Z/nZ)*上思考了,当n是合数的时候会漏掉一些下标。但是那个也好做。(p 2p...)这个用2p生成。(p^2 2p^2 ...)这个用2p^2生成。所以依然不是什么难事。
[/Quote]
回复 点赞
jdtxse 2010年06月27日
刚才留意的好多人,都好面熟。
回复 点赞
liutengfeigo 2010年06月27日
学习了~
回复 点赞
FancyMouse 2010年06月27日
挖还要研究合数的情况……n要是偶数的话那就大麻烦了。不想了周末购物去。
回复 点赞
FancyMouse 2010年06月27日
>2是2n-1的原根不能保证一个轮换就搞定吧?
这个当n是质数的时候能保证。那样的话题意所需的置换就(1 2 4 8 ...)这一个

不过p^k的时候p的确是问题……俺一直在(Z/nZ)*上思考了,当n是合数的时候会漏掉一些下标。但是那个也好做。(p 2p...)这个用2p生成。(p^2 2p^2 ...)这个用2p^2生成。所以依然不是什么难事。
回复 点赞
michael122 2010年06月27日
2是2n-1的原根不能保证一个轮换就搞定吧?
那篇论文就是找了p=3,2是p^2的原根,应该是你说的特殊情况
确实有一些n是可以一个轮换就做完了,但是这个n应该不好找
你说的2n-1=p^k时
(1 2 4 ... )是不够的
必须还有
(p 2p ...) 等等
因为 2 不能生成p
接下去的做法其实就是论文的做法了
回复 点赞
michael122 2010年06月26日
还必须要2n-1是素数才可以吧?
回复 点赞
FancyMouse 2010年06月26日
特殊情况其实一点意义都没有。如果2是mod 2n-1的原根的话那就按照1,2,4,...的顺序交换已经能达到效果了。满足原根条件的n要比2n=3^k-1的n要多得多。
回复 点赞
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.0w+

社区成员

3.4w+

社区内容

数据结构与算法相关内容讨论专区
社区公告
暂无公告