1. 程式人生 > >面試算法題

面試算法題

你是 混合 位長 查找 gen 回來 進制 關系 turn

前幾天面試了一家公司,給了兩個算法題目。覺得挺有意思的,當時面試回答的時候回答的不太好。隨後回來找了一下資料。記錄一下。

一、題目一

有1000瓶水,其中有一瓶有毒,小白鼠只要嘗一點帶毒的水24小時後就會死亡,至少要多少只小白鼠才能在24小時時鑒別出那瓶水有毒。樓主這個題目當時沒有回答出很好的方案。只想到了這個題目應該和二進制有聯系。回來後在網上查找了一下資料,既然有如此精妙的想法。

給1000個瓶分別標上如下標簽(10位長度):
0000000001 (第1瓶)
0000000010 (第2瓶)
0000000011 (第3瓶)
......
1111101000 (第1000瓶)
從編號最後1位是1的所有的瓶子裏面取出1滴混在一起(比如從第一瓶,第三瓶,。。。裏分別取出一滴混在一起)並標上記號為1。以此類推,從編號第一位是1的所有的瓶子裏面取出1滴混在一起並標上記號為10。現在得到有10個編號的混合液,小白鼠排排站,分別標上10,9,。。。1號,並分別給它們灌上對應號碼的混合液。24小時過去了,過來驗屍吧:
從左到右,死了的小白鼠貼上標簽1,沒死的貼上0,最後得到一個序號,把這個序號換成10進制的數字,就是有毒的那瓶水的編號。
檢驗一下:假如第一瓶有毒,按照0000000001 (第1瓶),說明第1號混合液有毒,因此小白鼠的生死符為0000000001(編號為1的小白鼠掛了),0000000001二進制標簽轉換成十進制=1號瓶有毒;假如第三瓶有毒,0000000011 (第3瓶),第1號和第2號混合液有毒,因此小白鼠的生死符為00000011(編號為1,2的鼠兄弟掛了),0000000011二進制標簽轉換成十進制=3號瓶有毒。

二、題目二

有n個人,其中一個明星和n-1個群眾,群眾都認識明星,明星不認識任何群眾,群眾和群眾之間的認識關系不知道,現在如果你是機器人R2T2,你每次問一個人是否認識另外一個人的代價為0(1),試設計一種算法找出明星,並給出時間復雜度。樓主當時回答出來了雙重循環的哪種情況。但是那種情況的時間復雜度是O(N*N)。

解法一:看到題目後,首先想到的是任選其中一個人作為目標對象,然後詢問剩下的n-1個人。若當前目標不認識其他人,但是其他人認識ta,則目標就是明星,否則,目標不是明星,在選擇其他人作為目標做同樣的詢問。時間復雜度為O(N*N).

解法二: 在解法一中,每次只是做了詢問而沒有記錄相關的信息,比如在詢問A和B時,有以下幾種關系:

1) A不認識B, B不認識A。==> A和B都不是明星

2)A認識B, B認識A。==> A和B都不是明星

3) A認識B, B不認識A。==> A不是明星,B可能是明星。

4)A不認識B, B認識A。==> A可能是明星,B一定不是明星

因為每次詢問都可以至少排除一個對象,因此只需要n-1次詢問即可找到目標。

總結如下:is A 認識 B? (yes) A不是明星,B可能是明星 : (no) A可能是明星,B是群眾。所以一次詢問可以確定一個人

  1 int func38(int a[], int n)
  2  {
  3       int i;
  4       int
stari = 0; //存放最小數在a中的位置 ,明星的位置 5 int flag = 0; 6 7 for (i=1; i<n; i++) 8 { 9 if(a[stari] > a[i])//如果stari標號的數小於i標號的數, 表示a[stari] 認識 a[i] 10 { 11 stari=i; 12 flag=0; //更換懷疑對象(最小數)時,標記清零 13 } 14 else if(a[stari] ==a[i]) //如果stari裏存放的確實是唯一最小數是不會跑進這裏來的 15 { 16 flag++; 17 } 18 } 19 if(flag>0) 20 return -1;//表示沒有明星,例如所有的數都相等 21 22 return stari; 23 }

參看:

http://lzj0470.iteye.com/blog/657579

http://www.cnblogs.com/legendmaner/archive/2013/05/24/3097248.html

面試算法題