面試題(整理了一下)

來源:互聯網
上載者:User
1、線形表a、b為兩個有序升序的線形表,編寫一程式,使兩個有序線形表合并成一個有序升序線形表h;
2、運用四色定理,為N個局域舉行配色,顏色為1、2、3、4四種,另有數組adj[][N],如adj[i][j]=1則表示i地區與j地區相鄰,數組color[N],如color[i]=1,表示i地區的顏色為1號顏色。
3、用遞迴演算法判斷數組a[N]是否為一個遞增數組。
4、編寫演算法,從10億個浮點數當中,選出其中最大的10000個。
5、編寫一unix程式,防止殭屍進程的出現.

同學的4道面試題,應聘的職位是搜尋引擎工程師,後兩道超級難,(希望大家多給一些算髮)
1.給兩個數組和他們的大小,還有一動態開闢的記憶體,求交集,把交集放到動態記憶體dongtai,並且返回交集個數
long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])
2.單連表的建立,把'a'--'z'26個字母插入到連表中,並且倒敘,還要列印!
3.可怕的題目終於來了
象搜尋的輸入資訊是一個字串,統計300萬輸入資訊中的最熱門的前十條,我們每次輸入的一個字串為不超過255byte,記憶體使用量只有1G,
請描述思想,寫出算髮(c語言),空間和時間複雜度,
4.國內的一些帖吧,如baidu,有幾十萬個主題,假設每一個主題都有上億的跟文章,怎麼樣設計這個系統速度最好,請描述思想,寫出算髮(c語言),空間和時間複雜度,

時間問題,我不發代碼了,但這些問題書上都有,我給你說一下書名

1、線形表a、b為兩個有序升序的線形表,編寫一程式,使兩個有序線形表合并成一個有序升序線形表h;
答案在 請化大學 嚴銳敏《資料結構第二版》第二章例題(有錯字不好意思 下同)

2、運用四色定理,為N個局域舉行配色,顏色為1、2、3、4四種,另有數組adj[][N],如adj[i][j]=1則表示i地區與j地區相鄰,數組color[N],如color[i]=1,表示i地區的顏色為1號顏色。
答案在 中國水利出版社 引進的一套國外《資料結構》教材上,單蘭色的封皮(這套書包括作業系統(利用的minux),多媒體都有,估計有年歲了)

3、用遞迴演算法判斷數組a[N]是否為一個遞增數組。
這個我沒在教才上看到過 但不難!!
一會貼代碼

4、編寫演算法,從10億個浮點數當中,選出其中最大的10000個。
用外部排序,在《資料結構》書上有!!!

5、編寫一unix程式,防止殭屍進程的出現.
你說的 殭屍進程 是死結嗎?unix程式我不會

1.給兩個數組和他們的大小,還有一動態開闢的記憶體,求交集,把交集放到動態記憶體dongtai,並且返回交集個數
long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])

這個我沒在教才上看到過 但不難!!
一會貼代碼

2.單連表的建立,把'a'--'z'26個字母插入到連表中,並且倒敘,還要列印!
這個有點讀不懂

3.可怕的題目終於來了
象搜尋的輸入資訊是一個字串,統計300萬輸入資訊中的最熱門的前十條,我們每次輸入的一個字串為不超過255byte,記憶體使用量只有1G,
請描述思想,寫出算髮(c語言),空間和時間複雜度,
的確可怕,

4.國內的一些帖吧,如baidu,有幾十萬個主題,假設每一個主題都有上億的跟文章,怎麼樣設計這個系統速度最好,請描述思想,寫出算髮(c語言),空間和時間複雜度.
的確可怕,

1、線形表a、b為兩個有序升序的線形表,編寫一程式,使兩個有序線形表合并成一個有序升序

二路歸併,不難
2、運用四色定理,為N個局域舉行配色,顏色為1、2、3、4四種,另有數組adj[][N],如adj[i][j]=1則表示i地區與j地區相鄰,數組color[N],如color[i]=1,表示i地區的顏色為1號顏色。
可轉化位元影像論問題,將各個地區視為圖上的點,相鄰的點之間連上一條線,構成一個無向圖,可得其鄰接矩陣,根據鄰接矩陣得色數.
3、用遞迴演算法判斷數組a[N]是否為一個遞增數組。
樓上有正解

4、編寫演算法,從10億個浮點數當中,選出其中最大的10000個。
用快排.可先從10億個浮點數當中選出第10000大的數,設位M,在選M位基值,利用一趟快速排序,M
之後的數即為所求.

1.給兩個數組和他們的大小,還有一動態開闢的記憶體,求交集,把交集放到動態記憶體dongtai,並且返回交集個數
long jiaoji(long* a[],long b[],long* alength,long blength,long* dongtai[])
我想到的是蠻力法,時間複雜度位O(alength*blength);想必大家都知道了!

2.單連表的建立,把'a'--'z'26個字母插入到連表中,並且倒敘,還要列印!
在建立單鏈表的時候使之逆序,不難.

3.可怕的題目終於來了
象搜尋的輸入資訊是一個字串,統計300萬輸入資訊中的最熱門的前十條,我們每次輸入的一個字串為不超過255byte,記憶體使用量只有1G,
請描述思想,寫出算髮(c語言),空間和時間複雜度,
255byte*300萬<1G;也就是說可全部調進輸入資訊,利用PAGERANK演算法實行頻率統計,排序即可.
注:PAGERANK演算法受google專利保護,看不到原始碼.

1、線形表a、b為兩個有序升序的線形表,編寫一程式,使兩個有序線形表合并成一個有序升序線形表h;
   已知:a[0]<a[1]  ...a[n-1]<a[n];
            b[0]<b[1]  ...b[n-1]<b[n];
   
    一、a[n]<b[0]
    二、b[n]<a[0]
    三、插入排序&&二分排序
   #include "stdio.h"
#include "conio.h"

main()
{
    int i,j,k;
    int h[20];
    int a[10]={2,5,6,9,11,24,56,78,80,81};
    int b[10]={1,3,8,7,10,21,32,45,65,79};
    i=0;
    j=0;
    for(k=0;k<20;k++)
       if(a[i]>b[j])
             { h[k]=b[j];j++;}
          else
             { h[k]=a[i];i++;}

    for(i=0;i<20;i++)
        printf("%d ",h[i]);

    getch();

}

//單連表的建立,把'a'--'z'26個字母插入到連表中,並且倒敘,還要列印!

node *p = NULL;
node *q = NULL;

node *head = (node*)malloc(sizeof(node));
head->data = ' ';head->next=NULL;

node *first = (node*)malloc(sizeof(node));
first->data = 'a';first->next=NULL;head->next = first;
p = first;

int longth = 'z' - 'b';
int i=0;
while ( i<=longth )
{
node *temp = (node*)malloc(sizeof(node));
temp->data = 'b'+i;temp->next=NULL;q=temp;

head->next = temp; temp->next=p;p=q;
i++;
}

print(head);

其實第四題這樣的題目樓上沒有人說對。
說是從10億個數中選,實際上是說數很多。當然用外部排序是一個方法。
估計想考的是看你會不會二叉排序樹。
10000個最大的數,就是10000個結點,這個記憶體是可以裝下的。
但10億個數就要從外部檔案讀出來了。每讀入一個/組,就試圖將之放入排序樹中。等10億個數全讀完了,10000個結點按中序輸出就行了。
我還在CSDN中見過類似的題目,答案也是二叉排序樹,好像沒人回答出來。

象搜尋的輸入資訊是一個字串,統計300萬輸入資訊中的最熱門的前十條,我們每次輸入的一個字串為不超過255byte,記憶體使用量只有1G,
請描述思想,寫出算髮(c語言),空間和時間複雜度,
這道題不是很難吧,用雜湊的方法,將這些字串雜湊到不同的桶中,然後判斷那個最多就行了

關於第4題的我寫的程式

#include <stdio.h>
#include <iostream>
#define MAX 1000000  //設定總數,我這裡設定了一百萬,也可以到一千萬,一億的話記憶體受不了,但是我的程式是串列讀出資料的,所以也是可以處理更大的資料的,這裡全部放在資料裡是為了方便
#define TOP 1000

void quicksort(int array[ ],int left,int right)
{
if(left < right)
{
        int div = array[right];
int i = left;
int j = right-1;
int temp;
if(i==j){//只有兩個資料,直接處理完了事
if(array[i] < div)
{
                array[i+1] = array[i] ;
                array[i] = div;
return;
}
}
else
{
while(i< j)
{
for( ; array[i] > div ; i++);
for( ; array[j] <= div ; j--);
if(i>=j)break;

temp = array[i];
array[i] = array[j];
array[j] = temp;

}

if(i!=right)
{      
array[right] = array[i];
array[i] = div;
}
            quicksort(array,left,i-1);
quicksort(array,i+1,right);

}
}
}

int main()
{

  int *Big = new int[MAX];
  int * pSort = new int[TOP*4];//最好pSort[0]-pSort[Top-1]為結果
  int i=0, j=TOP, k=0;
  int h=0;
  int all = 0;//Big資料計數器
  srand(time(NULL));
  for( i =0; i< MAX; i++)
  {
//int jj= rand( )%77 + 1;
//int nn = rand( )%jj;
        Big[i] = rand( );
//cout<<Big[i]<<" ";
  }

  //可加入一些測試資料,看看大的能否排到前面
  Big[0] = 100000;
  Big[10] =300002;
  Big[11] =200002;
  Big[MAX-2] =200007;

  int temp = Big[0];

  for( all = 0; all < TOP; all++)
  {
  pSort[all] = Big[all];
 
  } 
  quicksort(pSort,0,TOP-1); 
 
  //for( k =0;k<TOP-1;k++) cout<<pSort[k]<<"";
  //cout<<endl;
  temp = pSort[TOP-1];
  i = TOP-1;
  j = TOP*2;

  int sum = 0;
 
  for( all= TOP; all<MAX; all++)
  { 
    sum++;
if( Big[all]>temp )
{
     
sum++;

pSort[i++] = Big[all];
     
if(i==TOP*2) // i滿TOP*2了
{
sum += 3;
i = 0;
j = TOP*2;
int temp2 = pSort[TOP*2-1];

for(int n=0; n< TOP*2-1; n++)
{
sum += 2;

if(pSort[n]> temp2)
{
if(i!=n)pSort[i] = pSort[n]; //大的放到pSort前部分
i++;
}
else
{
pSort[j++] = pSort[n]; //小的放到pSort後部分
}

}

if(i<TOP)//i<100,選的分割數比較大, 重新選擇排在100名後的作為分割數
{
while(i<TOP)
{
sum += 5;

pSort[i++] = temp2;
j--;
temp2 = pSort[j];
k = TOP*2;
h = TOP*2;
for( ;k<j;k++)
{
sum += 2;

if(pSort[k]>temp2)
{
pSort[i++] = pSort[k];
}
else
{
if(h!=k) pSort[h] = pSort[k];
h++;
}
}
j = h;
} //i>100了,選擇排在100名後的分割數的操作完畢
}
sum++;
temp = temp2;
}
}
  }

  cout<<endl<<sum<<""<<i<<" "<<j<<endl; 
 
///////這裡是全排序輸出前TOP個,看看後面的結果是否和這個相同,但必須在MAX值比較小才可以執行,否則堆疊溢位/////
/*
  quicksort(Big,0,MAX-1);

  for(k=0; k<TOP; k++)cout<<Big[k]<<"";
  cout<<endl;
  cout<<endl;
*/
 //////////////////////////////////////////

  //輸出前TOP個
  quicksort(pSort,0,i-1);
  for( k =0;k<TOP;k++) cout<<pSort[k]<<"";

  getchar( );
  delete[ ] Big;
  delete[ ] pSort;
  return 0;
}

演算法的題不難啊。
我說個思路吧:
1、線形表a、b為兩個有序升序的線形表,編寫一程式,使兩個有序線形表合并成一個有序升序線形表h;
    這個問題和下面那個第一題本質是一樣的,我==一起說。

3、用遞迴演算法判斷數組a[N]是否為一個遞增數組。
    這個就是每次拿最後一個和邊界上的比下縮小規模,沒難度。

4、編寫演算法,從10億個浮點數當中,選出其中最大的10000個。
    外部排序

5、編寫一unix程式,防止殭屍進程的出現.
    和演算法沒關係。我不會。

1.給兩個數組和他們的大小,還有一動態開闢的記憶體,求交集,把交集放到動態記憶體dongtai,並且返回交集個數
    先排序O(N*LOG(N)),然後進行的步驟和第一題一樣就對了。對這題是:取小頭,比較,一樣進記憶體,不一樣小的扔O(N)內完成。加上排序O(N*LOG(N))搞定。
對上面那題  不用講應該都知道了,就是比完合并就行了。 

2.單連表的建立,把'a'--'z'26個字母插入到連表中,並且倒敘,還要列印!
    鏈表是基本功,沒什麼好說的。

象搜尋的輸入資訊是一個字串,統計300萬輸入資訊中的最熱門的前十條,我們每次輸入的一個字串為不超過255byte,記憶體使用量只有1G,
請描述思想,寫出算髮(c語言),空間和時間複雜度,
    我不知道。不過你算下就知道空間肯定是夠的:全部裝入都夠(當然我們不會這麼做)
4.國內的一些帖吧,如baidu,有幾十萬個主題,假設每一個主題都有上億的跟文章,怎麼樣設計這個系統速度最好,請描述思想,寫出算髮(c語言),空間和時間複雜度,
    我不知道。沒學過著方面知識

樓上幾個朋友回排序的,我們一起來討論一個問題。
結果要求的是10000個排好順序的數而已,並沒有要求你把10億個數都拿出來排序。
所以更有效率的思路應當是
1、讀入的頭10000個數,直接建立二叉排序樹。O(1)
2、對以後每個讀入的數,比較是否比前10000個數中最小的大。(N次比較)如果小的話接著讀下面的數。O(N)
3、如果大,尋找二叉排序樹,找到應當插入的位置。
4、刪除當前最小的結點。
5、重複步驟2,直到10億個數全都讀完。
6、按照中序遍曆輸出當前二叉排序樹中的所有10000個數字。
基本上演算法的時間複雜度是O(N)次比較
演算法的空間複雜度是10000(常數)

我來回答後面兩道“難題”吧:
1. 最近時有公司出這種從幾百萬詞條中找出頻率最大的前幾條或者重複的條目的問題。
對於這種問題實際上並不需要太多所謂的搜尋專業知識,想想資料庫是怎麼實現或者資料結構中關於詞典索引的章節就不難知道,這些題目的解決辦法不外乎,採用二種資料結構:
樹(二叉樹,Trie樹和B樹)和雜湊表。對於300萬詞條來說,構建一個開地址雜湊肯定用不了1G記憶體,如果還不放心,就構建一棵Trie樹,如果還怕記憶體不夠就構建B+樹進行多級索引。至於複雜度分析,稍微回憶一下你的資料結構書吧。
2.類似貼吧的設計無非是個多級索引,查詢與更新問題。
一級是個主題,10多萬主題為了效率直接雜湊就成,查詢時候這些主題肯定是要全部載入記憶體的;
二級索引是上億資料,查詢或者更新時記憶體肯定不能放呀,自然就要用B+樹。稍微補充一下,為啥要用B+樹就是為瞭解決記憶體中不能載入全部資料的時候用來分級載入資料,這樣可以充分利用記憶體的換入換出來解決海量資料操作的問題。這和作業系統的檔案系統設計以及資料庫實現原理是相似的。

4、編寫演算法,從10億個浮點數當中,選出其中最大的10000個。

記得, 排序演算法的時間複雜度是O(N*log N), 這個是最快了
但是這個地方時間複雜度是 O(N*log n),
其中N 是 1G, n 是 10K 大概是: 30/13
除此之外, 這個地方還不需要使用耗時巨大的外排序
像對於磁碟訪問遠遠慢於記憶體訪問的常規系統來說, 效率不在一個數量級。

class CSearch
{
public:
    void Input(float f)
    {
        if ( m_vBuf.size() < 10000 || f > *m_vBuf.begin() )
        {
            m_vBuf.insert(f);       // log(2, n) 時間複雜度
            if ( m_vBuf.size() > 10000 )
                m_vBuf.erase(m_vBuf.begin());
        }
     }

    std::set<float> m_vBuf;
};

剩下的, 就是把所有資料過一遍這邊就OK了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.