1. 程式人生 > >準備面試雜總

準備面試雜總

tails 排查 失敗 max AS 部分 gif http avl

1.求整數序列中的中位數。

//首先想到的是先排序,後直接就求出來了

//參照這位大佬:https://blog.csdn.net/cpu_12593/article/details/48231213 有種恍然大悟的感覺

//洛谷1168題就是

Ⅰ。利用快排查找關鍵字,隨機選取一個關鍵字進行劃分,第一次劃分的結果標記位置如果小於N/2,那麽就將右半的部分再執行一次這個算法(從選關鍵字開始);如果關鍵字位置大於N/2,就將其左半部分在執行這個算法;直到關鍵字標記位置=N/2,才結束。這樣的時間復雜度就是O(n),獲取中位數時間為O(1).

Ⅱ。利用數據結構平衡二叉樹(左右兩顆子樹的高度≤1,並且是遞歸定義的,左子樹小於根節點,右子樹相反。常用實現方法有紅黑樹,AVL樹,treap樹),每讀取一個那麽久插入到樹中,最終根節點就是中位數,但是二叉樹的插入調整算法比較復雜。時間復雜度為O(nlogn),獲取時間復雜度是O(n),或者是通過查找根節點,用數組來表示的?

Ⅲ。參照這個:https://blog.csdn.net/yhf_2015/article/details/52315689 代碼寫的真厲害

利用堆來實現。左邊是大頂堆,右邊是小頂堆,小頂堆中元素永遠要麽和大頂堆中元素個數相同,要麽比它多一個。也就是說將其平分為兩部分。

當有元素插入時,如果兩堆中元素個數相同,那麽就嘗試插入小頂堆中,插入的時候需要考慮,如果要插入的元素比小頂堆堆頂的元素小,那麽就把大頂堆堆頂的元素插入到小頂堆中,並且將新元素插入的大頂堆中(都是為了保持數量關系。)。否則直接插入小頂堆。

如果兩堆中元素個數不同(肯定是小頂堆中元素多了一個),那麽就嘗試加入大頂堆中,如果新元素比大頂堆堆頂元素大,那麽就把小頂堆堆定元素挪過來,並且將新元素插入小頂堆。否則直接插入大頂堆。

//但是有沒有這種情況就是把一個根去了之後,仍然仍然是不滿足條件,那還接不接著挪點了?

技術分享圖片
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int a1[maxn];
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &a1[i]);
    
    priority_queue <int> q1;//優先隊列默認是less,大頂堆。
    priority_queue <int
, vector<int>, greater<int> > q2;//greater小頂堆 int size1 = 0, size2 = 1; q2.push(a1[1]);//先放進 for(int i = 2; i <= n+1; i ++){ if(!(i&1))printf("%d\n", q2.top());//如果i是偶數的話,那麽就打印小頂堆的堆定元素 //。比如說現在該查第4個數,那麽前三個數中肯定是最小堆堆定元素是中位數。滿足了題目要求。 if(i > n) break; if(size2 > size1){ if(a1[i] > q2.top()){ q1.push(q2.top()), size1 ++; q2.pop(); q2.push(a1[i]); }else q1.push(a1[i]), size1 ++; }else{ if(a1[i] < q1.top()){ q2.push(q1.top()), size2 ++; q1.pop(); q1.push(a1[i]); }else q2.push(a1[i]), size2 ++; } } return 0; }//太厲害了
貼大佬的代碼

//真厲害,直接用優先隊列就可以實現啊,沒想到。。學習了。

2.c++中new和malloc的區別。

//真沒考慮過這個問題。都是把數據分配在堆區。

參考這個:https://blog.csdn.net/linux_ever/article/details/50533149

Ⅰ。申請內存所在的位置。malloc是分配在堆中,new:自由存儲區(那麽可否為堆呢?要根據operator new的實現來,其中參數是一個指針,可以指向堆或靜態區,在其處分配內存。或者甚至可以不分配內存)

Ⅱ。返回類型安全性。malloc返回是void*類型指針,需要進行強制類型轉換;new返回的是嚴格匹配對象類型的指針,不用強制類型轉換,是安全的。

Ⅲ。內存分配失敗後返回值不同。malloc會返回NULL,而new則返回bac_alloc。

Ⅳ。是否需要指定內存大小。new不需要。malloc需要制定。

Ⅴ。是否調用析構函數。使用new/delete會調用對象的構造函數和析構函數。但是malloc不會。

//先寫著幾點吧,寫多了也記不住。

3.堆和棧有什麽區別?

//堆中是通過malloc分配的,棧是存儲普通的類型變量,從低地址開始分配。其他的就像不知道了。

參考這位大佬:https://www.cnblogs.com/mysticCoder/p/4921724.html

棧的分配是由操作系統控制的,一般存放函數的局部變量等,使用完立即由操作系統釋放。

堆是通過程序員手動申請和釋放的,如果沒有,則程序結束後由OS自動回收。

堆中內存分分配容量比棧中大,說來也是,一些大的高位數組,直接普通定義不行,可以用new那麽就可以了。

碎片的問題:堆中會產生,但是棧是連續分配的不會產生,

生長方向:堆是向上生長即向著內存增加的方向;但是棧是相反的,是向著內存減小的方向。

分配效率:當然是棧高了。堆還需要調用一系列的算法來實現。

4.什麽是隨機變量?

//就是隨機生成的變量,比如java中用random生成,可以給它種子。不過這是概率論的知識嗎?emmm

簡單的說就是隨機事件的數量表現。包括離散性(伯努利概型)、連續性隨機變量(指數隨機變量)等。參考:百度百科隨機變量定義。

在一定條件下,並不一定出現相同結果的現象稱謂為隨機現象,其結果稱為隨機變量,比如任意時刻車站的人數。

5.如何反轉一個單鏈表?

//頭和尾調轉,肯定是不行了,是單向的,對稱調轉的話那肯定就每次都需要遍歷。。

參照這個:https://blog.csdn.net/hyqsong/article/details/49429859

Ⅰ。從原鏈表的頭部取元素插入到新鏈表的頭部

Ⅱ。每次都把原來的頭節點的後邊一個元素放到最前。

準備面試雜總