给定一个2n长数组,其中n个奇数和n个偶数,对数组进行排序将奇数放在前半部分,偶数放在后半部分。要求:
不改变原来的奇偶各自的相对顺序
只申请常数的空间
时间复杂度为O(n)
举例:给出1 2 3 4 5 6
排序后为 1 3 5 2 4 6
PS:请一定仔细阅读3个条件,去掉其中任意一个都变得简单,并且网上我搜到的答案都是缺少其中某个条件的。因此我怀疑这题是否有解。
看了大家的回答,基本可以分为2种情况:
用链表可以轻易解决这道题,当然如果把数组转成链表因为需要申请2n长度的next数组,所以认为还是申请额外空间了
只管输出,如果只要求输出结果那遍历2遍就行了,但这样题目变得太过简单
因为这是一道面试题,我想可以从上面2方面和面试官沟通,我只是凭记忆写下这题,其中也许有自己的一些思维定势(比如没有强调一定是数组,或者没有强调必须要求数组排序只要求输出)。看了大家的讨论还是很有启发的。
找到了国外的链接,看了一圈讨论大部分认为没有O(n)时间O(1)空间的解法
https://www.careercup.com/question?id=5201559730257920
另外说下我自己对这题的一个思考,可以观察到,假如一个数组是符合最终条件的,那么发现当且仅当只交换相邻的两个奇偶数是不会破坏相对顺序的,那么只需给出一个策略找出从最终状态转到题目起始状态的就行了。
另外,不要纠结于奇偶分别的大小问题,比如4 5 3 1 2 6和2 1 3 5 4 6是等价的,只是一个简单的替换,只要将奇数按1 3 5……这样的顺序,偶数按2 4 6……这样的顺序排好就行了。
Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
在你的3个条件限制下,数组不行,链表可以。
用链表还是很容易的吧,只是改变指针就可以了,遍历一次搞定,遇到偶数插入队尾(只改指针不申请内存),奇数就不管它,但如果还要对奇偶数各自排序基本不会有O(n)的算法
已经很多人说了, 用链表是很容易实现的,但是用数组却不行(保持稳定性,时间O(n),空间O(1)),如果谁可以,show your code,让我们膜拜你。
初看无解的问题,貌似也有解决的办法的,待我整理一下。
最好不要用大于length数字来测试,如果数据不大的话,应该没问题的,否则就要考虑溢出的问题了。
我是這樣想拉,不知道你覺得怎麼樣:
就從數組的頭開始走,碰到奇數不動,碰到偶數就把它放到數組的最後,直到搬動了 n 個偶數為止。
P.S. 為什麼給負分呢? 如果覺得答案有任何不妥的地方,可以先評論、討論之後再給別人負分,我不覺得有必要踩在這裡認真討論的人,對於負分充滿著疑惑...
我觉得是不可能的,其实归根结底,这是一个排序问题。
我们假设使用快排(当然不满足稳定性问题,这里只是随便说,想要稳定性可以用二叉树来排序),那么只要把比较条件设为奇数比偶数大就可以了。
但是很明显排序问题只有在某些特殊情况下才能O(n)。
所以我觉得不可能。
作为一般的排序问题来看,会让人觉得不可能,但是这个题目虽然3个条件很苛刻。
也有一些有利条件可以利用,重要的2点就是:
奇数和偶数一样多,所有数组长度就是 n + n
奇数和偶数保持原有顺序,不需要按大小进行排序
我用golang实现如下:
看了一下题目,简单的想了一下,思路如下:
如果是给出的数组,则没有办法能保持相对顺序不变。 下面代码只能满足条件2和3:
就是分别从最开始和最后面进行检查,四种情况,分别判断一下。
如果给出的是链表,上述的3个条件很容易满足。
另:莫名其妙的被踩。。。
很简单的
用计数排序
假定你的数字范围在0到65535范围之内,定义一个数组count[65536](这个空间是常量,和n无关,所以是O(1) ),初值全部为0。
那么假设有下面这些数字:
100
200
300
119
0
6
...
那么对于每个这个数字,都做在count中记录一下:
100 => count[100]++
200 => count[200]++
300 => count[300]++
119 => count[119]++
0 => count[0]++
6 => count[6]++
...
也就是说:
首先,遍历一遍所有这些数字就可得到0~65535每个数字的个数(在count数组中)
然后,再顺序遍历count数组,count[n] = m,则输出m个n,(比如说有count[3] = 2, 那么说明有2个数字3),依次输出,最后可得结果。
在输出时:
先输出奇数count[1],count[3]...
再输出偶数count[0],count[2]...
复杂度分析:
第一次遍历是O(n),第二次遍历是O(1),为常量,所以最后的时间复杂度为O(n),而空间复杂度为O(1)
PS:这个算法很简单,相信大家都会,只是这个题太过于变态了,一般会把面试者吓住
O=orgin list
N=[None]*2n
for i in O:
主要就是空间问题,不占用一个2n的空间应该是不能实现的,因为情况复杂,没法确定常数空间就够用!
js实现应该是这样的,偶数时释放一个,然后追加到末尾,当处理到初始数组最后一个时停止。 参考了前面moling3650的代码。。
刚我赞了@白汀 马上有人踩
可能有人觉得申请了n-1个空间,空间复杂度不是常量。
我用php来输出来验证下,事实上增加的内存是常量,php5.4测试增加内存量为:160