问题:有n个球,它们被标记为0、1、2,并且顺序混乱,我想按从小到大的顺序对它们进行排序。球:
1, 2, 0, 1, 1, 2, 2, 0, 1, 2, ...
我们必须使用最快的方法来解决,并且不能使用sort()函数,我想过很多方法,例如冒泡排序,插入排序等,但这并不是很快。是否有一种算法可以使时间复杂度变为O(logn)或O(n)?
给定的球列表A []和长度n
void sortBalls(int A[], int n)
{
//code here
}
答案 0 :(得分:9)
鉴于项目类型的数量非常有限(0
,1
和2
),您只需计算每种项目的出现次数。然后,要打印“排序的”数组,请重复打印每个标签的次数。运行时间为O(N)
int balls[N] = {...}; // array of balls: initialized to whatever
int sorted_balls[N]; // sorted array of balls (to be set below)
int counts[3] = {}; // count of each label, zero initialized array.
// enumerate over the input array and count each label's occurance
for (int i = 0; i < N; i++)
{
counts[balls[i]]++;
}
// sort the items by just printing each label the number of times it was counted above
int k = 0;
for (int j = 0; j < 3; j++)
{
for (int x = 0; x < counts[j]; x++)
{
cout << j << ", "; // print
sorted_balls[k] = j; // store into the final sorted array
k++;
}
}
答案 1 :(得分:1)
如果您事先知道少量可能的值,并且该值是您需要了解的有关球的所有信息(它们不包含其他属性),那么“排序”就相当于“计算那里的每个值有多少”是”。因此,您将生成一个直方图-从0到2的数组(在您的情况下)-遍历您的值并增加相应的计数。然后,您将生成一个数组,其中包含编号为0的n_0个球,编号为1的n_1个球和编号为2的n_2个球,瞧,它们已被排序。
显而易见,您不能低于O(n)-至少必须对每个值进行一次计数才能计数,对于n个值,这就是n次运算。