2014年百度实习生面试题及总结
通过这次面试,突然感觉自己弱爆了,故写此总结以记之。
思路:使用数组的下标和其值之和等于给定的数。(郁闷的是当时没有想出来!!)
具体方法:(假设给定的升序数组为a[]和整数n)
1) 新开辟一个数组b[]并初始化为零。
2) 对a[]进行遍历,同时对b[]进行赋值,即b[a[i]] = n-a[i]。
3) 对a[]进行第二次遍历,令a[i]=tmp,然后我们得到b[tmp],再判断b[b[tmp]]是否为零,若不为零则成功找到了而个数tmp和b[tmp],然后退出。若遍历完a[]后没有找到则寻找失败。
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、找出下列代码中存在的错误。
int cal(uint num)
{
uint sum;
for(; a>=0; a--)
{
sum = sum + num*num;
}
return sum;
}
错误: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函数的实现。
虽然看起来这个题目很简单,但是能很好的把实现写出来并不是那么容易。当时在笔试的时候,考虑的问题太多了。
尤其是考虑了目的串的空间大小,如果小于源字符串的长度时会产生错误或异常,于是在字符串拷贝之前考虑如何获取源字符串的长度,因为不能直接sizeof(src),所以我就对源字符串做了次遍历,得到了源字符串的长度,然后想获取dest指向的空间大小,这样就遇到问题了,因为dest指向的空间不像src那样有结束标志,所以在此不知道如何获得dest所指向空间的大小。然后我就问了面试官怎么求得dest指向的空间大小,他说也不知道。好吧,这部分就搁置在这了,然后用了一个循环将源字符串复制给dest。
在这道简单的代码实现题中,我感觉对C++中的内存空间分配太敏感了,想的太多了,其实真的很简单。
在strcpy函数中计算源字符串的长度虽然不可以使用sizeof计算字符串的大小,但可以使用strlen,另外目标串指针指向的空间大小我现在也不知道如何获取。
char *(strcpy)(char *s1, const char *s2)
{
char *s = s1;
for(s=s1; (*s++ = *s2++)!='\0'; );
//或者使用 while((*s++ = *s2++)!='\0');
return (s1);
}
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.
核心代码:
int r=a[0]%d;
for(i=1; i<len; i++) //len为大数的长度
{
r = (r*10+a[i])%d;
}