O n 時間解決的面試題 名人問題

2022-09-17 02:45:16 字數 1473 閱讀 9629

問題描述

有n個人他們之間認識與否用鄰接矩陣表示(1表示認識,0表示不認識),並a認識b並不意味著b認識a,也就意味著是個有向圖

如果乙個人是名人,他必須滿足兩個條件,乙個是他不認識任何人,另乙個是所有人必須都認識他。

分析問題

首先,我們從中可以分析出,名人必定最多只有1個,因為如果有兩個名人ab,那麼你說他們倆是否認識呢,考慮a是名人,那麼b必定認識a,得出b必定不是名人,與b是名人的條件衝突,因為名人不認識任何人

解決問題

用乙個陣列儲存所有沒檢查的人的編號,遍歷陣列中的兩個人i,j。

如果i認識j,則i必定不是名人,刪除i

如果i不認識j,則j必定不是名人,刪除j

最終會只剩下乙個人,我們檢查一下這個人是否是名人即可,如果是,返回這個人,如果不是,那麼這n個人中並無名人

編寫**

//初始化陣列編號

for(int i=a;i

a[i]=i;

}while(n>1)

else

}//最終檢查a[0]是否為名人

for(int i=0;i

//不考慮自身,並且檢查他是否認識某個人,如果認識,那麼不是名人

//檢查其他人是否認識他,如果有人不認識他,那麼他也不是名人

if((a[0]!=i)&&(known[a[0]][i]||!known[i][a[0]]))

return -1;

}return a[0];

演算法優化

以上演算法需要用乙個陣列來儲存沒有檢查的人的編號,意味著空間複雜度為o(n),是否可以讓空間複雜度降低到o(1)呢,答案是肯定的,解決方法就是用一頭掃的方法

這裡我們就不需要用乙個陣列來儲存沒有檢查的人的編號了,我們直接對n個人進行遍歷

遍歷的方式是定義兩個下標,用兩個下標一起往後掃,對於兩個下標i,j而言,保證[o~i-1]沒有名人,並且[i~j-1]也沒有名人,如果i認識j,那麼i不是名人,刪掉i,刪除的方法就是i=j,j++,如果i不認識j,刪除j,刪除的方式是j++,遍歷的時候讓j一直加就可以了。

int i=0;j=1;

for(;j

if(known[a[i]a[j]])

i=j;

}for(j=0;j

if((i!=j)&&(known[i][j]||!known[j][i]))

return -1;

}return i;

演算法優化2

除了一頭掃的優化方式,也可以用兩頭掃的方式優化以上的演算法

保證0~i-1沒有名人,並且j+1~n也沒有名人

如果i認識j,刪除i

如果i不認識j,刪除j

i=0;j=n-1;

while(i

if(known[i][j])

else

}for(j=0;j

if(i!=j&&(known[i][j]||!known[j][i]))

return -1

}return i;

面試題 賽馬問題

據說,這是google的面試題。面試題目如下 一共有25匹馬,有乙個賽場,賽場有5個賽道,就是說最多同時可以有5匹馬一起比賽。假設每匹馬都跑的很穩定,不用任何其他工具,只通過馬與馬之間的比賽,試問,最少得比多少場才能知道跑得最快的5匹馬?不能使用撞大運的演算法 很明顯這是乙個演算法題,網上有很多貼子...

SQL問題(面試題)

面試完後在本地mysql資料庫中重現了該問題 資料表stuscore資訊如下 1 計算每個人的總成績,並且排名 要求顯示字段 學號 姓名 總成績 select stuid as 學號,name as 姓名,sum score as 總成績 from stuscore group by stuid o...

解決小公尺公司的面試題

題目 一副從1到n的牌,每次從牌堆頂取一張放桌子上,再取一張放牌堆底,直到手上沒牌,最後桌子上的牌是從1到n有序,設計程式,輸入n,輸出牌堆的順序陣列。c 放入桌子上陣列 public static int v new int 0 public static int m new int 0 stat...