一道排序笔试题,在o(n)时间内对一个数组进行排序

时间:2022-06-04 17:15:21
题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。

分析:估计有很多人应该都看过这个题目,仅仅作为自己面试找工作的一个记录哈,大家见笑了。

由于我们常见算法最快也不过是o(nlogn)时间,所以自然不能套用常见算法。这里,我们的想法是构建一个辅助数组b,这个数组b初始存储的数全初始化为0。然后,我们对给定的员工数组a进行一次遍历,将员工年龄作为b数组下标,每遇到一次就将b数组对应单元里面存储的数+1,这样一次遍历之后就可以统计出每个年龄在公司里面有几人。接下来我们往a中填充数据,从年龄为0的开始,看b[0]中存的数字是多少,我们就往a[0]开始的位置往后填充几个0,;然后是年龄为1的,出现几次就接着往后填充几个1,以此类推。这样,最终完成了对员工数组a的排序。说是排序,其实这里只是按照年龄从前到后依据每个年龄的出现次数重新往给定数组里面填充数组罢了,并不涉及大小的交换。

因为员工年龄撑死也就几十岁的范围,故我们的辅助数组容量只要常量99也就够用了,这里无论有几万员工,都够用,与员工数n无关,故符合

o(1)辅助空间的要求。

下面附上代码,用的是java实现(本代码非完整可用代码,也未给出真正的员工数组,只是写下思路,大家有兴趣的话还请自己用random方法构建员工年龄数组,并对代码进行相应修改)

public class Test{

public static void main(String[] args){

public final int max_age = 100;

   int[] timesOfAge = new int[max_age];

sortAge(timesOfAge);

}

public static void sortAge(int[]age){

int i,j,index;

    if(ages == NULL || length <= 0)//length是员工数组的长度

        return;

 

       

 

    for(i = 0; i < length; i++)

    {

        int age = ages[i];

         ++timesOfAge[age];

    }

 

    index = 0;

    for(i = 0; i < max_age; i++)

    {

        for(j = 0; j < timesOfAge[i]; j++)

        {

            ages[index] = i;

            ++index;

        }

    }

}

}