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函數的實現。

雖然看起來這個題目很簡單,但是能很好的把實現寫出來並不是那麼容易。當時在筆試的時候,考慮的問題太多了。

尤其是考慮了目的串的空間大小,如果小於源字符串的長度時會產生錯誤或異常,於是在字符串拷貝之前考慮如何獲取源字符串的長度,因爲不能直接sizeof(src),所以我就對源字符串做了次遍歷,得到了源字符串的長度,然後想獲取dest指向的空間大小,這樣就遇到問題了,因爲dest指向的空間不像src那樣有結束標誌,所以在此不知道如何獲得dest所指向空間的大小。然後我就問了面試官怎麼求得dest指向的空間大小,他說也不知道。好吧,這部分就擱置在這了,然後用了一個循環將源字符串複製給dest。

在這道簡單的代碼實現題中,我感覺對C++中的內存空間分配太敏感了,想的太多了,其實真的很簡單。

在strcpy函數中計算源字符串的長度雖然不可以使用sizeof計算字符串的大小,但可以使用strlen,另外目標串指針指向的空間大小我現在也不知道如何獲取。

標準的寫法爲:

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

char *(strcpy)(char *s1, const char *s2)
{
    char *s = s1;
    for(s=s1; (*s++ = *s2++)!='\0'; );
    //或者使用 while((*s++ = *s2++)!='\0');
    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>



發佈了33 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章