---恢復內容開始---
一、單項選擇題
1、從n個未排序的數中尋找中位數(第[n/2]大的數),平均時間複雜度最優演算法的複雜為:
a.o(logn) b.o(n) c.o(nlogn) d.o(n^2)
分析:求無序陣列的中位數2、普通pc機器上四位元組有符號整數能表示的最小數是多少?中位數即是排過序後的處於陣列最中間的元素。 不考慮陣列長度為偶數的情況。設集合元素個數為n。
簡單的想了下:
思路1) 把無序陣列排好序,取出中間的元素
時間複雜度 採用普通的比較排序法 o(n*logn)
如果採用非比較的計數排序等方法, 時間複雜度 o(n), 空間複雜度也是o(n).
思路2)
2.1)將前(n+1)/2個元素調整為乙個小頂堆,
2.2)對後續的每乙個元素,和堆頂比較,如果小於等於堆頂,丟棄之,取下乙個元素。 如果大於堆頂,用該元素取代堆頂,調整堆,取下一元素。重複2.2步
2.3) 當遍歷完所有元素之後,堆頂即是中位數。
思路3) 熟話說,想讓演算法跑的更快,用分治!
快速排序之所以得名"快排
",絕非浪得虛名!因為快排就是一種分治排序法!
同樣,找中位數也可以用快排分治的思想。具體如下:
任意挑乙個元素,以改元素為支點,劃分集合為兩部分,如果左側集合長度恰為 (n-1)/2,那麼支點恰為中位數。如果左側長度
, 那麼中位點在右側,反之,中位數在左側。 進入相應的一側繼續尋找中位點。
這種方法很快,但是在最壞的情況下時間複雜度為o(n^2
), 不過平均時間複雜度好像是o(n)。
引申一:
查詢n個元素中的第k個小的元素(來自程式設計珠璣)
程式設計珠璣給出了乙個時間複雜度o(n),的解決方案。該方案改編自快速排序。
經過快排的一次劃分,
1)如果左半部份的長度》k-1
,那麼這個元素就肯定在左半部份了
2)如果左半部份的長度==k-1
,那麼當前劃分元素就是結果了。
3)如果。。。。。。。1
,那麼這個元素就肯定在右半部分了。
並且,該方法可以用尾遞迴實現。效率更高。
時間複雜度分析, 由於差不多每次都是把序列劃分為一半。。。假設劃分的元素做了隨機優化,時間複雜度近似於
n+n/2+n/4.... = 2n*(1-2^-(logn)) 當n較大時 約等於 2n 也就是 o(n)。
看來,快速排需的用處可大著咧。。。
也用來查詢可以n個元素中的前k個小的元素,前k個大的元素。。。。等等。
引申二:
查詢n個元素中的第k個小的元素,假設記憶體受限,僅能容下k/4個元素。
分趟查詢,
第一趟,用堆方法查詢最小的k/4個小的元素,同時記錄剩下的n-k/4個元素到外部檔案。
第二趟,用堆方法從第一趟篩選出的n-k/4個元素中查詢k/4個小的元素,同時記錄剩下的n-k/2個元素到外部檔案。
。。。第四趟,用堆方法從第一趟篩選出的n-k/3個元素中查詢k/4個小的元素,這是的第k/4小的元素即使所求。
3、根據程式,寫輸出?
#includeusing分析:輸出1 2 3 2namespace
std;
void foobar(int a,int *b,int **c)
intmain()
4、從選3個數字組成乙個集合,不允許兩個相鄰的數字在乙個集合中,那麼有多少種選擇方法?816
分析:這個題可有兩種方法來做:
第一種,先求總數,然後減去不符合要求的,即:c(20,3)-c(18,1)-(1+2+3+...+17)*2=816
第二種,c(20,3)-c(18,1)*c(19,1)+c(18,1),意思就是相鄰的兩個數共有19對,任取一對,剩餘還有18個數再任取乙個即c(19,1)*c(18,1)但是重複減了一次三個數相鄰情況。。最後加上c(18,1)
5、1024!末尾有幾個0?
分析:1024/5+1024/5^2+1024/5^3+1024/5^4+...=253
6、2^n個元素中挑選最大的元素,至少要做多少次比較?
分析:2^n-1次
7、選擇哪些是穩定排序:
分析:詳見
8、知道二叉樹的前序、中序和後續遍歷,二推一,那個不可能?
分析:前序+後續-/>後續。。其他可以。。
9、程式訪問記憶體的效能與下列哪個方面無關?
a.記憶體匯流排的頻寬
b.記憶體頁面的訪問的特權級別
c.cpu片內的cache大小
d.程式讀寫記憶體的連續性
10.下列關於unix檔案系統的說法中,正確的是?
應用程式可以採用記憶體對映的方式讀取檔案資料
二、程式設計與演算法
1、給定2個大小為n,m的整數集合,分別存放在兩個陣列中int a[n],b[m],輸出兩個集合的交集?
private直接hash。。static setsetmethod(int a,int
b)
for(int j=0; j)
return
set2;
}
2、銀行取款排隊模擬
3、o(n)時間複雜度對數值範圍0到n^2-1的n個數進行排序
#include #includeusing
namespace
std;
int n, radix, length_a, digit = 2
;void print(int *a, int start, int
end)
cout
<
<
基數排序呼叫的穩定排序
void stable_sort(int *a, int *b, int k, int
d)
//c[i]表示所以<=i的數字出現過的次數
for(i = 1; i <= k; i++)
c[i] = c[i] + c[i-1
];
//初始化b為0,b用於輸出排序結果
for(i = 1; i <= length_a; i++)
b[i] = 0
;
for(j = length_a; j >= 1; j--)
delete c;
delete d;}//
基數排序
void radix_sort(int *a, int *b)
}int
main()
;
inti;
//生產n個隨機的資料範圍在0到n^-1之間
for(i = 1; i <= n; i++)
while
(flag[a[i]]);
flag[a[i]] = 1
; }
print(a,
1, n);
radix =n;
radix_sort(a, b);
print(a,
1, n);
return0;
}
谷歌 Google 2023年校園招聘筆試題
筆試一共有10個選擇題和3個程式設計演算法題,google的要求是前面的選擇題至少正確6個以上,判卷人才會看後面的三個演算法題。下面是回憶版的筆試題,有的已經記不起來了,有可能回憶的不太準確。大家看看這些題,在找工作的時候有個參考,好運 一 選擇 1 以下哪個字串不能被正規表示式 a bc?d 匹配...
谷歌2013校園招聘筆試題
1.4 小組賽,每個小組有5支隊伍,互相之間打單迴圈賽,勝一場3分,平一場1分,輸一場不得分,小組前三名出線。平分抽籤。問乙個隊最少拿幾分就有理論上的出線希望 a.1 b.2 c.3 d.4 分析 設有a b c d e 5支球隊,假設abc晉級了。如果球隊c積1分可以出現,由於是單迴圈賽,說明他4...
2010谷歌校園招聘筆試題
1 哪個表示式不能用這個匹配 a bc d?a.ad b.abcd c.abc d.abccd 2 intel x86 cpu中,哪種運算最慢 a 加b.減 c.乘d.除 3 下面程式的輸出 include using namespace std intmain else system pause ...