给定一个数组,该数组具有递增顺序直到最大值然后按降序排列的数字。
Eg. int a[] = { 10, 12, 14, 16, 15, 13, 11}.
如何有效地对这个数组进行排序?
数组需要就地排序。
答案 0 :(得分:7)
找到最大值,然后将数组反转到该值。然后对两个子数组应用合并 - 首先包含最大值和剩余数组。这将具有线性计算复杂性,并且将需要线性额外存储器。
在你的情况下:
a[] = { 10, 12, 14, 16, 15, 13, 11}
=> {10,12,14,16}, {15,13,11}
=>反向(线性,就地)=>
{16,14,12,10}, {15,13,11}
=>合并(线性,附加线性存储器)=>
{16,15,14,13,12,11,10}
编辑:有关如何在没有额外内存的情况下合并两个数组,请查看this answer
答案 1 :(得分:5)
我的解决方案:
选择2个数组的开头和数组的结尾。
进入结果数组,从两个指针写入一个min(或者如果你需要以降序排序,则为max) 指向1位置的指针(开始指针+1位置和结束指针-1 位置
重复直到开始指针将放在结束指针之后。
解决方案的复杂性是O(N)。 所需内存为O(N)
<强>伪代码:强>
function Sort(a)
{
startPointer = 0;
endPointer = a.length-1;
result = new Array of size a.length
while (startPointer <= endPointer)
{
var newValue;
if (a[startPointer] < a[endPointer])
{
newValue = a[startPointer];
startPointer +1
}
else
{
newValue = a[endPointer];
endPointer -1
}
result[a.length - startPointer - endPointer] = newValue;
}
return result;
}
更新问题的解决方案:
作为解决方案,我们对数组的第一部分进行了部分排序。
指针(10和11) {10,12,14,16,15,13,11}
指针(12和11) 交换12和11 {10,11,14,16,15,13,12}
指针(14和12) 交换14和12 {10,11,12,16,15,13,14} //将指针从14移动到13更小。
现在我们已经为{16,15,13,14}排序{10,11,12}和子问题(子问题的N减少两次)
此算法的复杂性为:O(N)+(N / 2)+ O(N / 4)+ ...总是O(N)
图片以便更好地说明:
答案 2 :(得分:2)