2014年百度实习生面试题及总结

通过这次面试。突然感觉自己弱爆了。故写此总结以记之。


1、给定一个升序的整型数组和一个整数,请在数组中找出二个数使得这二个数的和等于所给定的这个数,若存在多组整数满足条件。则输出随意一组就可以。要求时间复杂度为O(n)。

思路:使用数组的下标和其值之和等于给定的数。

(郁闷的是当时没有想出来!

。)
详细方法:(如果给定的升序数组为a[]和整数n)
1) 新开辟一个数组b[]并初始化为零。
2) 对a[]进行遍历,同一时候对b[]进行赋值,即b[a[i]] = n-a[i]。
3) 对a[]进行第二次遍历,令tmp=a[i],然后我们得到b[tmp],再推断b[b[tmp]]是否为零。若不为零则成功找到了而个数tmp和b[tmp],然后退出。若遍历完a[]后没有找到则寻找失败。

注:此方法有一种情况未考虑到,当数组存在一个数k,且n=2*k时。这样的情况需进行单独考虑,数组仅仅有一个k时,则不满足。若存在两个k时符合条件。

另外,能够从数据的两側分别进行遍历,此方法仅仅需对数组进行一次遍历就可以。

(第一次想到此方法时感觉不正确,后来通过证明。此方法是正确的)


2、有四十亿个不同的正整数,如今要推断一组数据a,b,c,d…是否在这四十亿个数据中。
思路:直接採用散列表。
详细方法:
1) 开辟一个非常大的bool类型的数组a[],初始化为false。由于每一个bool类型变量仅仅占一位。40亿个bool变量须要空间500MB左右的空间。


2) 对四十亿个数据做一次遍历,对每一个数k,我们将a[k]=true。


3) 如今对于随意个数n,仅仅需查看a[n]是否为true,若为true,则存在,否则不存在。



3、找出下列代码中存在的错误。

<span style="font-size:18px;">
int cal(uint num)
{
    uint sum;
    for(; a>=0; a--)
    {
        sum = sum + num*num;
    }
    return sum;
}</span>
错误:
1) sum没有初始化。
2) for循环是个死循环,由于a是个无符号的整形,总是>=0。所以是个死循环。
3) sum可能会溢出,sum是个无符号的整形,但在返回时给了一个有符号的整形,因而可能溢出。

4、有一个整数矩阵。矩阵中每行都是从低到高有序,每列相同从低到高有序。现给定一个数。推断这个数是否在这个整数矩阵中?
假如如今有例如以下矩阵A是m*n的矩阵,当中m=4, n=5。
1    2    5    7    14
3    4    10    15    18
6    9    12    17    22
8    11    13    21    25
如今我们要推断15是否在矩阵中。
思路:将二分查找推广到二维空间。
详细方法:
1) 矩阵的行从0-3,列0-4。依据二分查找的思想。 row_mid=3/2=1, column_mid=4/2=2。我们能够找到A[1][2]。


2) 由于A[1][2]=10 < 15。而且矩阵的随意行和列都是升序排列,所以15仅仅可能存在于a区,b区和c区中,例如以下图所看到的。



3) 依次对以上的三个区域进行递归查找就可以。

5、写出strcpy函数的实现。

尽管看起来这个题目非常easy。可是能非常好的把实现写出来并非那么easy。当时在笔试的时候,考虑的问题太多了。

尤其是考虑了目的串的空间大小,假设小于源字符串的长度时会产生错误或异常。于是在字符串拷贝之前考虑怎样获取源字符串的长度。由于不能直接sizeof(src),所以我就对源字符串做了次遍历。得到了源字符串的长度,然后想获取dest指向的空间大小。这样就遇到问题了,由于dest指向的空间不像src那样有结束标志,所以在此不知道怎样获得dest所指向空间的大小。然后我就问了面试官怎么求得dest指向的空间大小,他说也不知道。

好吧,这部分就搁置在这了。然后用了一个循环将源字符串复制给dest。

在这道简单的代码实现题中,我感觉对C++中的内存空间分配太敏感了。想的太多了,事实上真的非常easy。

在strcpy函数中计算源字符串的长度尽管不能够使用sizeof计算字符串的大小,但能够使用strlen,另外目标串指针指向的空间大小我如今也不知道怎样获取。

标准的写法为:

<span style="font-size:18px;">

char *(strcpy)(char *s1, const char *s2)
{
    char *s = s1;
    for(s=s1; (*s++ = *s2++)!=''; );
    //或者使用 while((*s++ = *s2++)!='');
    return (s1);
}
 </span>

6、给定一个数字字符串即一个大数,和一个数d,求这个大数对d的余数r。也就是大数求余问题。属于数论里面的东西。

(简单题,但当时竟然没做出来。!!)
分析:首先要清楚大数求余原理,
(a+b)%n = (a%n + b%n)%n;
(a*b)%n = ((a%n) * (b%n))%n;

如567%d = r。
r = ((((5%d)*10+6)%d)*10+7)%d.

核心代码:

<span style="font-size:18px;">
int r=a[0]%d;
for(i=1; i<len; i++)        //len为大数的长度
{
    r = (r*10+a[i])%d;
}</span>



原文地址:https://www.cnblogs.com/yangykaifa/p/6863446.html