给出integer array
之类的
int numbers[8]={1, 3, 5, 7, 8, 6, 4, 2};
前阵列中的半边是奇数,其余(等量数) 是的。奇数按升序排列,偶数部分按降序排列。排序后,数字的顺序无法更改。
我如何选择时间复杂度 而不是O(n^2)
和空间复杂度O(1)
?
对于此示例,结果将是:{1,8,3,6,5,4,7,2}
;
我不能使用外部数组存储,但可以使用临时变量。
我尝试使用两个指针(oddPtr, evenPtr
)分别指向奇数和偶数,并移动evenPtr
以将偶数值插入奇数的中间。(如插入排序)<登记/>
但它需要O(n^2)
。
更新
答案 0 :(得分:2)
根据Dukeling的评论,我意识到我提出的解决方案实际上并不是线性的,而是线性的,甚至更糟 - 你无法控制它是否需要额外的内存。在我的第二个想法中,我意识到你对阵列有很多了解,你可以实现更具体,但可能更简单的解决方案。
我将假设数组中的所有值都是正数。我需要这个,以便我可以使用负值作为“已处理”标志。我的想法如下 - 从左到右遍历数组。对于每个元素,如果它已被处理(即它的值为负),只需继续下一个元素。否则,您将得到一个常量公式,其中该元素的位置应为:
i
,则应移至i*2
i
,则应移至(i - n/2)*2 + 1
将此值存储到临时值并将值设置为数组0的当前索引。现在直到我们手头的值不为零的位置,将其与保留在我们应该的位置的值交换根据上面的公式放置它。此外,当您将值放在手边时,将其标记为“将其标记为已处理”。现在我们有一个新的价值'手头',我们再次根据上面的公式计算它应该去哪里。我们继续移动值,直到我们手边的值应该移到0的位置。稍微想一想你可以证明你手头上永远不会有负面('处理')价值,最终你会最终在阵列的空位。
处理完所有值后,在数组上迭代一次以取消所有值,您将获得所需的数组。我描述的算法的复杂性是线性的 - 每个值不会超过一次“手头”,你将迭代它不超过一次。