返回   cpper编程论坛 > 算法
注册账号 论坛帮助 会员列表 日历事件 搜索 今日新帖 标记版面已读

回复
 
LinkBack (5) 主题工具 显示模式
  5 links from elsewhere to this Post. Click to view. #1 (permalink)  
旧 2008-04-20
Meta 的头像
版主
 
注册日期: 2004-12-02
帖子: 226
文章: 5
Meta 正向着好的方向发展
默认 Array Puzzle

[题目描述]输入a1,a2,...,an,b1,...,bn,如何用O(n)的时间,O(1)的空间,将这个序列顺序改为a1,b1,...,an,bn。

大家讨论一下解法吧.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #2 (permalink)  
旧 2008-04-20
bankrock 的头像
高级会员
 
注册日期: 2003-12-11
帖子: 843
文章: 7
bankrock 正向着好的方向发展
默认 回复: Array Puzzle

一种解法,不严格符合题目要求,因为要用到n个bit指示位。
设这个Array为A, 取i为第一个和最终结果元素不同的位置,A[i]元素应该摆放到的位置为next[i],根据i的不同next[i]两种情况:
1. 1 <= i <= n: 此时A[i] = a[i],next[i] = 2*i - 1;
2. n < i <= 2*n: 此时A[i] = b[i-n],next[i] = 2*(i - n);
将A[next[i]]存储到临时变量中,根据上面的两步循环得到next[next[i]]的值以及赋予和它位置对应的正确元素,依次类推,可以得到一个摆放正确的元素的环路。
在上述过程中记录下已经摆放正确的位置,然后取i为第一个和最终结果元素不同的位置,继续查找其他环,最后可以得到正确的结果。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #3 (permalink)  
旧 2008-04-21
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: Array Puzzle

其实如果把这个数列看成一个长度为2n的数列,每一项分别为a[0]到a[2n-1],那么转换以后的数列b有b[x] = a[x%2*n+x/2]。
可以使用交换的方法来做,把a[1]记下,然后从a[1]开始,运用上面的公式找到对应的元素,依次循环,可以确保只使用一个额外存储。但是这个是不完善的,因为这样的交换最终会形成一个环,而如果这个环不足以覆盖所有的元素,就需要进行下一次循环,而怎样计算下一次循环的起始点是个问题,我没找到统一的规律。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #4 (permalink)  
旧 2008-04-21
bankrock 的头像
高级会员
 
注册日期: 2003-12-11
帖子: 843
文章: 7
bankrock 正向着好的方向发展
默认 回复: Array Puzzle

Pora的解法和我说的是一回事...
其实可以用一个2n-bit的向量表示2n个元素是否已经包含在某个环里,查找下一个环时从当前位置查找2n-bit的向量,整个过程也是O(n)时间复杂度,不过就是空间复杂度违背题意。

现在还有一种想法是:
1.把A中的a1,a2,...,an翻转,得到A=[an,a(n-1),...,a2,a1,b1,b2,....,b(n-1),bn];
2.取最开头的两个元素和最末尾的两个元素,交换an和b(n-1),得到A=[b(n-1),a(n-1),A',a(n),b(n)],交换a(n-1),b(n-1)得到A=[a(n-1),b(n-1),A',a(n),b(n)]
3.递归对A'作第二步所示的处理,最终可以的到A=a(n-1),b(n-1),a(n-3),b(n-3)....a(n-2),b(n-2),a(n),b(n)。这时其实可以将问题转换为一个特殊的in-place merge问题。设ab=a,b;假设此时n为偶数,如果要将A转换为最终形态,需要将A=[ab(n-1)ab(n-3)....ab(1)],[ab(2),ab(4),...,ab(n-2),ab(n)] merge为A=ab(1),ab(2),....,ab(n)。

现在的情况是好像没有O(n)的in-place merge算法,不过这里是个特殊情况,不知道可不可以简化一下
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #5 (permalink)  
旧 2008-04-25
初级会员
 
注册日期: 2008-04-25
帖子: 1
mice123 正向着好的方向发展
帖子 回复: Array Puzzle

这题的关键是数组中元素位置变化前后的关系。

令输入数组N为{d0,d1,...dn-1}

对于偏移 k ∈ [0, n), 定义f为:


f = 2k when k∈ [0, n/2)
f = 2(k - n/2) + 1 when k ∈ [n/2, n)

例如:
N: 1,3,5,2,4,6
k: 0,1,2,3,4,5

对于位置1的元素3, 转换后的位置为f(1) = 1 * 2 = 2
对于位置3的元素2, 转换后的位置为f(3) = 2 * ( 3 - 6/2) + 1 =1

剩下的就是根据公式写程序,这里用N[1]这个位置作为交换空间,k存储N[1]中元素的原始位置

代码:
#include<stdio.h> int main(){2k when k∈ [0, n/2) int sample[12] = {1,3,5,7,9,11,2,4,6,8,10,12}; int n = sizeof(sample)/sizeof(int); int i=0; int k=1; int temp; do { if(k<n/2){ temp = sample[1]; sample[1]= sample[2*k]; sample[2*k] = temp; k = 2*k; } else{ temp = sample[1]; sample[1] = sample[2*k - n + 1]; sample[2*k - n + 1] = temp; k = 2*k - n + 1; } }while(k!=1); for(i=0;i<n;i++) printf("%d",sample[i]); printf("\n"); return 0; }
中间少了步证明,呵呵,复杂度O(n),大家多拍哈

此帖于 2008-04-25 11:59 PM 被 mice123 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #6 (permalink)  
旧 2008-04-26
liuxinyu 的头像
高级会员
 
注册日期: 2006-02-09
帖子: 303
文章: 48
liuxinyu 正向着好的方向发展
默认 回复: Array Puzzle

我给一个交换策略,但是算法复杂度为O(n^2)
思路是:
第一步,交换,n和n+1位置上的元素,也就是an和b1,序列变为a1,a2,...,b1,an,b2,...,bn
第二步,交换,n-1和n, n+1和n+2,序列变为a1,a2,...,an-1,b1,b2,an,...,bn
...
第i步,交换,(n-i,n-i+1), (n-i+2, n-i+3),...,(n+i-1, n+i)位置。

程序如下:
代码:
#include <cstdlib> #include <iostream> using namespace std; void trans(int* x, int n){ for(int i=1; i<n; ++i) for(int j=0; j<i; ++j) std::swap(x[n-i+2*j],x[n-i+2*j+1]); } void print_list(int* x, int n){ for(int i=0; i<n; ++i) std::cout<<x[i]<<","; std::cout<<"\n"; } int main(int argc, char *argv[]) { int a[]={1,3,5,7,9,2,4,6,8,10}; print_list(a, sizeof(a)/sizeof(int)); trans(a, sizeof(a)/sizeof(int)/2); print_list(a, sizeof(a)/sizeof(int)); }
测试如下
chen@chen-PC /cygdrive/d/liuxinyu/temp/c++
$ g++ main.cpp

chen@chen-PC /cygdrive/d/liuxinyu/temp/c++
$ ./a
1,3,5,7,9,2,4,6,8,10,
1,2,3,4,5,6,7,8,9,10,
这里显然有冗余交换。所以时间复杂度才没有达到O(n),但是交换策略非常一致。

此帖于 2008-04-26 11:04 PM 被 liuxinyu 编辑.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #7 (permalink)  
旧 2008-04-28
Elminster 的头像
超级版主
 
注册日期: 2002-09-09
帖子: 1,763
Elminster 正向着好的方向发展
默认 回复: Array Puzzle

To Pora and Bankrock

想了一下,也木有想出来。感觉上你们的解法是正解,问题就在于,要更换的位置序列构成了一个环,我们要解决两个问题:

1. 证明这个序列总是头尾相接的一个环,而不会回到中间的某个元素。
2. 在回到第一个元素之后,如何判断下一个没有调整到正确位置的元素是哪个。

还得再想想。

To mice123

你用的方法其实就是 Pora 他们的。但是你没有考虑上面两个问题。

To liuxinyu

你的方法倒是别具一格,不过感觉难以改进的样子 ……
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #8 (permalink)  
旧 2008-04-29
polyrandom 的头像
超级版主
 
注册日期: 2002-09-03
帖子: 3,135
文章: 20
polyrandom 正向着好的方向发展
默认 回复: Array Puzzle

引用:
作者: Elminster 查看帖子
1. 证明这个序列总是头尾相接的一个环,而不会回到中间的某个元素。
2. 在回到第一个元素之后,如何判断下一个没有调整到正确位置的元素是哪个。
1很好证明,但是2我没有找出来。我尝试了一些,没啥好的规律。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
  #9 (permalink)  
旧 2008-05-03
Elminster 的头像
超级版主
 
注册日期: 2002-09-09
帖子: 1,763
Elminster 正向着好的方向发展
默认 回复: Array Puzzle

引用:
作者: polyrandom 查看帖子
1很好证明,但是2我没有找出来。我尝试了一些,没啥好的规律。
嗯,解决 1 不难,但是 2 想了两天也没有头绪,看样子走这条路很可能不通。换种思路,用交换我现在得到了一个 O(n*logn) 时间的算法,但是好像也没法继续改进了。
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
回复时引用此帖
回复

书签

主题工具
显示模式

发帖规则
不可以发表新主题
不可以发表回复
不可以上传附件
不可以编辑自己的帖子

启用 BB 代码
论坛启用 表情符号
论坛启用 [IMG] 代码
论坛禁用 HTML 代码
Trackbacks are 启用
Pingbacks are 启用
Refbacks are 启用

LinkBacks (?)
LinkBack to this Thread: http://www.cpper.com/c/t4838.html
作者 For Type 日期
&#12304;&#36319;&#30528;pongba&#24605;&#32771;&#12305;&#20063;&#26159;&#19968;&#36947;&#38754;&#35797;&#39064; - TopLanguage | Google Groups This thread Refback 2008-05-24 03:21 PM
&#12304;&#36319;&#30528;pongba&#24605;&#32771;&#12305;&#20063;&#26159;&#19968;&#36947;&#38754;&#35797;&#39064; - TopLanguage | Google Groups This thread Refback 2008-05-23 08:37 PM
&#12304;&#36319;&#30528;pongba&#24605;&#32771;&#12305;&#20063;&#26159;&#19968;&#36947;&#38754;&#35797;&#39064; - TopLanguage | Google Groups This thread Refback 2008-05-20 05:30 PM
TopLanguage | Google This thread Refback 2008-05-20 03:42 PM
Untitled document This thread Refback 2008-05-20 03:12 PM

相似的主题
主题 主题作者 版面 回复 最后发表
一道关于数组的题 zero 算法 20 2006-06-12 06:26 PM
How To Organize Template Source Code zweily C/CPP/TMP/GP 14 2004-10-08 11:45 PM
[原创]如何组织使用模版技术的源代码(翻译自The Code Project) zweily 技术杂烩 0 2004-07-16 11:46 PM
[BMP]文件格式 codinggirl 技术杂烩 3 2004-07-01 09:40 PM
[XLS]excel格式 famel 技术杂烩 1 2004-07-01 08:58 PM


所有时间均为格林尼治时间 +9。现在的时间是 07:57 AM


Powered by vBulletin® 版本 3.7.0
版权所有 ©2000 - 2008,Jelsoft Enterprises Ltd.
(C) Copy Right All Right Reserved 2001 - 2007

Search Engine Friendly URLs by vBSEO 3.1.0