49.一道看上去很吓人的算法面试题(排序、算法):
如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)
思路:这道题,我刚看到时直接吓尿了。。。差点颠覆三观。直接看其他大神的思路。
此题请看下文,作者张羿:
看上去似乎任何已知的算法都无法做到,如果谁做到了,那么所有的排序方法:QuickSort,
ShellSort,HeapSort,BubbleSort等等等等,都可以扔掉了,还要这些算法干吗阿,呵
呵。不过实际上,在数字范围有限制的情况下,是有一个这样的算法的,只需要用一个数组
记录每个数字出现次数就可以了。
假定你的数字范围在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),依次输出,最后可得结果。第一次遍历是O(n),第二次遍历是O(1),
为常量,所以最后的时间复杂度为O(n),而空间复杂度为O(1)
这个算法很简单,相信大家都会,只是这个题太过于变态了,一般会把面试者吓住(我原来
面试也出过这个题,只不过题目的表述形式要“友善”的多,呵呵)
看完上面大神的解法,我直接跪了,这也算是O(n),空间复杂度为O(1)的解法。。。在一定范围内,定义一个足够大的数组就算是O(1)的空间复杂度,我都有点想说脏话了。。不过,也没别的想法了。还是感谢这位大神,给我们开了眼界。。