本文参考了https://discuss.leetcode.com/topic/32929/o-n-o-1-after-median-virtual-indexing/2,代码参考了https://discuss.leetcode.com/topic/41464/step-by-step-explanation-of-index-mapping-in-java。
首先,我们使用快排的思想对原数组进行中位数的查找,同时保证比中位数大的排在数组前面,然后是中位数,最后是比数组小的数。在之前o(nlgn)解法中,我们排序好的数组重新排序,即从头开始,奇数位置从前往后取原数组,偶数位置,从中位数往后取,其实取法有很多种,都是为了防止数组的相等的数冲突。在这里,采取防止冲突方法是:即比中位数小的先排最后的偶数位置,比中位数大的先排前面的奇数位置,中位数补空。(这样来看,中位数大于2个,无法满足题意的排序)
index 0 1 2 3 4 5 6 7
L1 L2 L3 M M s1 s2 s3
virtual index 1 3 5 7 0 2 4 6
M L1 s1 L2 s2 L3 s3 M
可以看出virtual index = (1+2*index) % (len | 1)
这个只是暂时定义,其实最后得出结果并不是严格按照以上顺序来的。
利用三次切分,将numbers[virtual index]和中位数进行比较,如果numbers[virtual index]大,就应该放在前面,所以交换当前指针指向数字;相等,指针继续移动;否则,应该放在后面,交换数字而且当前指针不动。