今天发在群里的UC笔试题简要分析

本文探讨了一个特定的数组重排序问题,要求在O(n)的时间复杂度及O(1)的空间复杂度下将长度为2n的数组进行重排序。通过对数组元素的巧妙操作,实现了原地排序,避免了额外的空间开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目如下:有一个长度为2n的数组{a1,a2,a3……an,b1,b2,b3……bn},希望排序后{a1,b1,a2,b2,a3,b3……an,bn},要求时间复杂度O(n),空间复杂度O(1)。

分析:这题的难度在于空间复杂度O(1)。

有些朋友可能会想只需要从0和n/2处依次取数轮流放入新数组就能完成排序,但是这样空间复杂度就需要O(n)了,所以新建数组是不可行的,要想保持空间复杂度O(1),只能使用有限数目的变量,通过换项的方式来完成任务。

数组名我们就它叫arr[]吧~根据要求:
ai(原数组编号arr[i-1])放入arr[2i-2]
bi(原数组编号arr[n+i-1])放入arr[2i-1]
这样就需要分两类来讨论~有没有更简单的方法呢~我们不妨先来试试看~(以下不再使用ai、bi只写arr中的编号)

原数组:0,1,2,……n-1,n,n+1,n+2,……2n-1

新数组:0,  ,2,  ,4……,2n-2

原数组中的0,1,2……n-1分别对应新数组中的0,2,4……2n-2

原数组中的n,n+1,n+2,……2n-1还没有完成对应,而新数组中的1,3,5,……,2n-1位置也空着等待填充

如果让没对应的部分继续按照之前的规则对应(i对应2i)会是什么样子的呢。

原数组:(0,1,2,……n-1,)(n,n+1,n+2,……2n-1)

新数组:(0,  ,2,  ,4……,                            2n-2) (2n,2n+2,2n+4,……,             4n-2)

为了便于观察我把a、b用括号分别括起来了~

这么看起来我们似乎把数组扩大了一倍~但是数组相邻元素间存在着间隔而且恰好还能再存入一个元素~我们只需要把后面的b组数据全部提前一定距离(2n-1)就能恰好插入a组数据的空位了

a组(0,  ,2,  ,4……,                            2n-2)

b组   (1,  ,3,  ,5……,                           2n+1)

合并之后刚好是我们需要的结果:1,2,3,4,5……2n-2,2n-1

总的来说只需要把i放入2i mod(2n-1)即可~

不妨设原编号为x,新遍号为y,y=2*x mod (2n-1)~

现在要求x,

y为奇数时表示商1,y=2x-(2n-1),x=(y+(2n-1))/2

y为偶数时表示商0,y=2x,x=y/2

综上:x=(y+y%2(2n-1))/2

在eclipse下编程测试了下发现个小问题明天再来修改~数组长度取10的时候arr[3]和arr[6]不会被遍历到,因为它们互相调用,而我的算法是x=(y+y%2(2n-1))/2;arr[y] = arr[x];y = x;循环再找下一个被替换掉的位置~(为了节省空间避免挤掉还未被移走的数据~)

PS:文章中充满了“~”,这个只是个人语癖~和按位取反运算符无关~

以下是源代码:



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值