我被赋予了一个任务来对一个填充了(非负)整数的数组进行排序。
应对它们进行排序,使输出的顺序如下:
我尝试编写一个应该在O(n)下运行的简单算法(任务是有效地编写代码)。
但是我觉得它很乱,有些情况不起作用(例如当我尝试一个阵列时,前几个数字的余数为3)。
有关如何修复它的建议或更好的方法吗?
public static void sortByFour(int[] arr)
{
int zeroR = -1, oneR = 0, twoR = arr.length-1, threeR = arr.length;
do
{
if (arr[oneR]%4==1)
oneR++;
else if (arr[oneR]%4==0)
{
zeroR++;
int temp = arr[oneR];
arr[oneR] = arr[zeroR];
arr[zeroR] = temp;
oneR++;
}
else if (arr[oneR]%4==2)
{
twoR--;
int temp = arr[oneR];
arr[oneR] = arr[twoR];
arr[twoR] = temp;
}
else if (arr[oneR]%4==3)
{
threeR--;
int temp = arr[oneR];
arr[oneR] = arr[threeR];
arr[threeR] = temp;
}
} while (oneR < threeR && oneR < twoR);
}
答案 0 :(得分:4)
bucket sort可以帮到你。请注意,您可以通过循环4次(每个提醒一次)来克服桶排序的O(n)
额外空间因子,类似于(类似Java的伪代码):
final int REMINDER = 4; //4 because you use %4
int curr = -1;
for (int r = 0; r < REMINDER ; r++) {
for (int i = curr + 1; i < arr.length; i++) {
if (arr[i] % REMINDER == r) {
//swap elements:
int temp = arr[i];;
arr[i] = arr[++curr];
arr[curr] = temp;
}
}
}
这个想法是“记住”你最后设置元素的位置,并迭代数组4次,并将带有匹配提醒的元素交换到所需的位置(你记得)。
复杂性仍为O(n)
,O(1)
额外空间。
另一个是O(n)
(但更好的常量)O(n)
空间的时间是使用经典的桶排序,单个传递根据所需的提醒将所有元素存储在4个不同的列表中,在第二遍 - 在这4个列表中,根据所需顺序用原始数组填充元素。