首页
社区
课程
招聘
[旧帖] 一道算法题,求解。 0.00雪花
发表于: 2013-4-27 23:31 10046

[旧帖] 一道算法题,求解。 0.00雪花

2013-4-27 23:31
10046
原题如下:

有一个长度为2n的数组,元素顺序为(a1,a2,...,an,b1,b2,...,bn)
请设计一算法,对该数组进行操作,操作后的元素顺序为(a1,b1,a2,b2,...,an,bn)
要求该算法的时间复杂度为O(n),空间复杂度为O(1)

求朋友们帮忙解答一下。可以是C/C++代码或者伪代码,谢谢!

补充一下:这个算法不是能达到目的就行了,关键在于算法的时间复杂度和空间复杂度有要求。。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (23)
雪    币: 2993
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
这个是用指针?
2013-4-28 00:02
0
雪    币: 41
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
int a[2n]={a1,a2,a3,a4,a5,b1,b2,b3,b4,b5};
int b[2n]={0};
//b[2n]={a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,};
int k=0, g=0;
for(int i=0,i<2n,i++)
{
        if(i%2=0)
        {
           b[i]=a[k++];
        }
        else
        {
           b[i]=a[n+(g++)];
        }
}

for(int i=0,i<2n,i++)
{
        a[i]=b[i];
}
2013-4-28 00:43
0
雪    币: 75
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
a[2n] ={a1,.....,an,b1,.......,bn};
temp;
for(i=1;i<n-1;i+=2)
{
     temp = a[i];
    a[i] = a[n-1+i];
    a[n-1+i] = temp;
}
2013-4-28 07:41
0
雪    币: 336
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
我是学生,刚学数组,斗胆试一下。
int m[2n]={a1,a2,…an,b1,b2,…bn};
int a[n],b[n],i;
for(i=0;i<n;i++)
     a[i]=m[i];
for(i=0;i<2*n-1;i++)
     b[i]=m[i];
for(i=0;i<2*n-1;i++)
{
     if(i%2==0)
     m[i]=a[i/2+1]
  else
       m[i]=b[(i+1)/2];
}
2013-4-28 08:57
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
[QUOTE=memii;1171436]我是学生,刚学数组,斗胆试一下。
int m[2n]={a1,a2,…an,b1,b2,…bn};
int a[n],b[n],i;
for(i=0;i<n;i++)
     a[i]=m[i];
for(i=0;i<2*n-1;i++)
     b[i]=m[i];
for(i=0;i<2*n...[/QUOTE]

亲,你的这个算法很明显空间复杂度不符合要求哦
2013-4-28 14:11
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
[QUOTE=zLINKo;1171394]int a[2n]={a1,a2,a3,a4,a5,b1,b2,b3,b4,b5};
int b[2n]={0};
//b[2n]={a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,};
int k=0, g=0;
for(int i=0,i<2n,i++)
{
        if(i%2=0)
        ...[/QUOTE]

有一点很明显,那就是空间复杂度不是O(1)。。。
2013-4-28 14:12
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
不限。不过一般都是指针。
2013-4-28 14:13
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
[QUOTE=djxcon;1171415]a[2n] ={a1,.....,an,b1,.......,bn};
temp;
for(i=1;i<n-1;i+=2)
{
     temp = a[i];
    a[i] = a[n-1+i];
    a[n-1+i] = temp;
}[/QUOTE]

你这个算法不能达到题目要求的排列顺序。分析一下循环:
为了避免混淆,数组命名为A[2n]
当 i=1 时
    temp = A[1]   //  A[1]为a2
    A[1] = A[n]    //  A[n]为b1
    A[n] = temp
那么这趟循环后的排列为
a1,b1,a3,a4,....,an,a2,b2,b3,...,bn

当 i=3 时
   temp = A[3]    // A[3]为a[3]
     A[3] = A[n+2] // A[n+2]为b[3]
    A[n+2] = A[3]
那么这趟循环后的排列为
a1,b1,a3,b3,...,an,a2,b2,a4,b4,...,bn

依次类推,你会发现这个序列根本就不符合题意。
2013-4-28 14:29
0
雪    币: 1392
活跃值: (5147)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
10
wo 2 le
xian mark
2013-4-28 14:53
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这里的空间复杂度O(1)是指算法的额外空间消耗为常量级别。也就是说,不论我数组是多大,你实现这个功能的算法的额外空间需要是常量数值(可以大于1)。比如楼上的一些朋友另外定义一个b[n]数组,这里的数组长度很明显是跟规模n有关,就不是常量级O(1)了。
2013-4-28 14:59
0
雪    币: 1392
活跃值: (5147)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
12
[QUOTE=gdutlison;1171597]这里的空间复杂度O(1)是指算法的额外空间消耗为常量级别。也就是说,不论我数组是多大,你实现这个功能的算法的额外空间需要是常量数值(可以大于1)。比如楼上的一些朋友另外定义一个b[n]数组,这里的数组长度很明显是跟规模n有关,就不是常量级O(1)了。[/QUOTE]

需要在一个数组内操作??
还是有两个数组。 每个都是2n??
2013-4-28 16:50
0
雪    币: 1035
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
先放个思路,算法复杂度 应该是符合楼主要求的,不过答案正确性就不好说了
当 N 为 2 3 6 7 10 15 19 27 30 31 34 ... 答案是符合要求的
N为其他值时的 错误原因已经找到,解决方法尚在思考。
#include <stdio.h>
#define N (10)

void Show(int *pnAry, int n);
void Change(int *pnAry, int n);

int main()
{
    int nAry[2*N] = {0};

    int i = N;

    while (i--)
    {
        nAry[i] = i;
        nAry[N+i] = i*10 + 1;
    }

    Show(nAry, 2*N);

    Change(nAry, N);

    Show(nAry, 2*N);
    return 0;
}

void Show(int *pnAry, int n)
{
    int i = 0;
    for(;i<n;i++)
    {
        printf("%3d", pnAry[i]);
    }
    puts("");
}

void Change(int *pnAry, int n)
{
    int i = 1;
    int nNext, nPrev;
    nNext = pnAry[1];
    while (i != n)
    {
        nPrev = nNext;
        if (i<n)
        {
            i = 2*i;
        }
        else
        {
            i = (i-n+1)*2-1;
        }
        nNext = pnAry[i];
        pnAry[i] = nPrev;
    }    
    pnAry[1] = nNext;
}
2013-4-28 19:46
0
雪    币: 336
活跃值: (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我刚学到数组,连指针都不知道,还有你说的空间复杂度,还没学。
如果不考虑你的要求,我写的这个行不行?
2013-4-28 22:25
0
雪    币: 1035
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
2013-4-29 04:12
0
雪    币: 1035
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
2013-4-29 04:24
0
雪    币: 1689
活跃值: (379)
能力值: ( LV15,RANK:440 )
在线值:
发帖
回帖
粉丝
17
#include<math.h>
#include<stdio.h>

void reverse( int a[],int len )
{
    int i;
    for( i = 0;i < len/2;i++)
    {
        a[i] ^= a[len-1-i];
        a[len-1-i] ^= a[i];
        a[i] ^= a[len-1-i];
    }
}
void rshift( int a[],int len,int m )
{
    reverse( a,len - m );
    reverse( &a[len-m],m );
    reverse( a,len );
}

void do_cycle( int a[],int len,int start )
{
    int tmp,k = start;
    tmp = a[k];
    for(;;)
    {
        int t = ((k+1)*2)%(len+1)-1;
        if( t == start )
        {
            a[t] = tmp;
            break;
        }
        a[t] ^= tmp;
        tmp ^= a[t];
        a[t] ^= tmp;
        k = t;
    }
}

void shuffle( int a[],int len )
{
    int m = 0,k=0,i;
    if( len % 2 || len <= 0 )
        return;
    if( len == 2 )
    {
        int tmp = a[0];a[0]=a[1];a[1]=tmp;
        return;
    }
   
    k = log( len )/log(3.0);
    m = (pow( 3,k)-1)/2;
   
    rshift( &a[m],len/2,m );

    for( i = 1; i < 2*m;i *= 3 )
    {
        do_cycle( a,2*m,i-1);
    }

    shuffle( &a[2*m],len - 2 * m );
}
#define N 6
int main()
{
    int i,a[2*N]={11,12,13,14,15,16,21,22,23,24,25,26};
    shuffle(a+1,2*N - 2 );

    for( i = 0;i < 2*N;i++)
        printf("%d ",a[i] );
    printf("\n");
    return 0;
}
2013-4-29 15:49
0
雪    币: 183
活跃值: (36)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
没正经学过计算机,不太懂题目的要求。
不过,如果是在实际中解决问题的话,我会这样想:算法应该以数据结构为基础。连续存储的一维数组,显然在排序上并没有什么优势,但如果使用链式存储,那解决起来就轻松多了。
2013-4-29 22:14
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
其实这题也不算排序。
2013-4-30 01:28
0
雪    币: 25
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
你的代码有些错误。

int m[2n]={a1,a2,…an,b1,b2,…bn};
int a[n],b[n],i;
for(i=0;i<n;i++)
     a[i]=m[i];
for(i=0;i<2*n-1;i++)  //这里会数组下标越界
     b[i]=m[i];
for(i=0;i<2*n-1;i++)
 {
     if(i%2==0)
     m[i]=a[i/2+1]
  else
       m[i]=b[(i+1)/2];
} 
2013-4-30 01:36
0
雪    币: 183
活跃值: (36)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
21
边续存储线性表的实现,我只想到了一种方法,好像有点作弊。
先用汇编伪描述下。

_result equ this word;结果数组与原数存指向同一地址
_source dd 2*n dup(0);用来存放长度为2N的数组,键盘接收

xor di,di
mov cx,n
a:
mov word ptr [_result+di+2],[_result+di+n*4]
add di,4
loop a

用C的话,若是TC
long f[2n]={……};
int *p=(int*)f;
int *q=(int*)f(n);

for (int i=0,i<n,i++)
{
(&(p+1))=(&q);
p+=2;
q+=2;
}
那么INT f[]就是所求的数组。

太晚了,实属梦游。应该是*(P+1)=*(p+2n)
2013-4-30 01:39
0
雪    币: 125
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
这是数据结构课的作业么?
2013-4-30 03:29
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
平时做算法题都不考虑时间复杂度,空间复杂度,
2013-4-30 09:58
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
我倒是有一个算法:
设计三个下标缓存,设置一个可以放置两个数据的缓存。从尾向前变,每次取出两个,放到缓存,然后调换三个下表缓存指向的值。宿舍比较吵 ,实现还没完成~ 下午去图书馆做了给你传。
2013-4-30 13:06
0
游客
登录 | 注册 方可回帖
返回
//