人人校园招聘笔试题 vs 算法导论练习题

偶然在网上看到了人人校园招聘的两道笔试题:

1、给定一个有序数组a,长度为len,和一个数X,判断A数组里面是否存在两个数,他们的和为X,bool judge(int *a, int len, int x),存在返回true,不存在返回false

2、给定有n个数的数组a,其中超过一半的数为一个定值,在不进行排序、不开设额外数组的情况下,以最高效的算法找到这个数:int find(int *a, int n)

题目甚是眼熟,个人认为都是算法导论的书后练习题。

其中,第1题是算法导论2.3-7的原题(这里的算法不是最优,对于已排序的数组有O(n)的算法),并且题目中给出的数组a已经排序了,所以省去了2.3-7中排序的环节

第2题是算法导论4-6的变形,算法描述为:成对比较a中的元素,如果两个一样则将此数值作为元素放在数组中,不一样的剔除出数组,这样当数组中的元素都一样时,得到的就是那个数。代码需要一个指针,指向每次插入数值的位置,每次递归调用find,通过指针与a的差计算n作为参数。

int find(int *a, int n)
{
    int *pos;
    int i;
    int len;
    pos = a;

    if (1 == n)//递归停止条件 
    { 
        return a[1]; 
    }

    for (i=0; i+1 < n; i+=2)//相等的元素存入数组 
    { 
        if (a[i] == a[i+1]) 
        { 
            *pos = a[i];
            pos++; 
        } 
    } 

    len = pos - a; 

    if ((n%2 != 0) && (0 == len%2))//处理n是奇数且一次递归后剩余元素数为偶数的情况
    {
        *pos = a[n];
        len += 1;
    }

    return find(a, len);
}



因为D(n)=O(n),C(n)=O(1),所以递归式为T(n)=T(n/2)+O(n),所以算法的时间复杂度为O(n)。

find没有验证,仅供参考



你可能感兴趣的:(其他)