熟悉的陌生人;及又見Google搜尋之星分析

紫鳳發表於2013-07-23

今日面試題:熟悉的陌生人

大家都知道facebook使用者都是雙向的好友,a是b的好友,那麼b一定是a的好友,現在給定一個使用者列表,其中有些使用者是好友,有些不是,請判斷,這些使用者是否可以劃分為兩組,並且每組內的使用者,互相都不是好友。如果能,請給出這個劃分。

例子1:

使用者:{1, 2, 3}

好友關係:1-2, 2-3

劃分:{1,3} {2}

例子2:

使用者{1,2,3,4}

好友關係:1-2, 2-3, 3-4,4-1

劃分:{1, 3}{2, 4}

==================================

又見Google之星分析

原題

給定一批查詢日誌,數量為n。其中,有的查詢出現了多於n/3次,請線上性時間內,找到所有滿足條件的查詢。

分析

如果初次遇到這個問題,我們會有什麼樣的思路呢?

  1. 採用hashmap進行計數,O(n)的空間,O(n)的時間
  2. 進行排序,O(nlogn)
  3. 快速選擇演算法,這個也可以做到O(n)的時間。

但是,如果面試官進一步限制了可以採用方法的範圍:不允許使用上述方法,該如何處理呢?

我們在之前的面試題目中,遇到過類似的一個問題:那次的查詢出現的次數是一半以上。大家還記得,我們的解法麼?道理很簡單,但解法是很巧妙的,當我們每次去掉兩個不相同的查詢,那最終剩下的查詢,就是我們要找的查詢——這個查詢的出現次數,佔了一半以上。

那如果是多於n/3次呢?更一般的情況下,如果是多於n/m次呢?道理完全一樣的:我們每次去掉m個不同的查詢,那最終剩下的查詢,就是我們要找的備選的。道理很簡單,可是要如何實現呢?之前的題目,是比較簡單就能夠實現每次去掉兩個不同的查詢的,更一般的情況下,如何每次去掉m個不同的元素呢?

下面我們會介紹一種實現方法,核心的原理就是:每次去掉m個不同的查詢。第一個方法,是很有趣的一個方法,相信能夠給大家以啟發。

一種有趣的實現

有一個經典的遊戲,叫做俄羅斯方塊。想必很多同學都玩過的吧,俄羅斯方塊,有不同顏色、不同形狀的方塊,從上往下落,如果砌滿一行,這一行就會消失。一般列數都是固定的,在玩兒的過程中不會變化。這裡要講的一個實現,就是從俄羅斯方塊這個遊戲啟發而來的。

我們申請一個大小為m的map,開始遍歷查詢日誌,如果:

  1. 遇到一個不在map中的查詢,則插入map中,並且將值設定為1(相當於新落下一個方塊)
  2. 遇到一個在map中的查詢,則將map中,該查詢對應的值加1(相當於在已有的方塊上又多加了一個)

當map中的查詢個數等於m時,則對map中所有查詢的值減一(相當於砌滿了一層,就會消掉)。直到遍歷完畢查詢日誌,map中還存在的查詢,就是我們要找的查詢的備選。我們看下面的具體的例子:

查詢日誌為:4 3 3 2 1 2 3 4 4 7 且m=5

上述方法的步驟如下:

當 4 3 3 落入到map中的時候,map的形狀如下:

3 
4  3 

當 2 1 2 3 落入到map中的時候,map形狀如下:

  3     
  3     2
4 3  1 2

當 4 4 落入到map中的時候,map的形狀如下:

4  3     
4   3    2  
4 3   1  2  

當 7 落入到map中的時候,map形狀如下:

4 3      
4 3   2  
4 3 1 2 7

此時,map的大小=5,可以消除一行了。

消除之後如下圖:

4 3      
4 3   2  

此時剩下三個查詢,但不都是滿足條件的查詢,需要逐個驗證。O(n)即可。

分析上述方法的空間複雜度為O(m).當m=3時,就可以認為是常數空間。那麼時間複雜度呢?切要看map是如何實現的,如果是基於樹的,整個的時間複雜度O(nlogm),m=3時,可以認為是O(n)的。

【分析完畢】

本文來自微信:待字閨中,2013-07-18釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。

相關文章