面試題40 最小的K個數

2021-10-03 14:54:58 字數 3908 閱讀 2726

面試題40:輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。

//方法一:使用c++標準庫sort,時間複雜度o(nlogn)

class

solution

};

基於快速排序的劃分思想,使用partition對陣列進行劃分;如果基於陣列的第k個數字來劃分,使得比第k個數字小的所有數字都位於陣列的左邊,比k個數字大的所有數字都位於陣列的右邊。這樣調整之後,位於陣列中的左邊的k個數字就是最小的k個數字

#if 1

//方法二:快排

class

solution

output.

assign

(input.

begin()

, input.

begin()

+k);

return output;

}int

partition

(vector<

int>

& input,

int low,

int high)

input[low]

= pivot;

return low;}}

;#elif 0

//對整個序列進行快排

class

solution

v[low]

= pivot;

return low;

}void

quicksort

(vector<

int>

& v,

int low,

int high)

}

vector<

int>

getleastnumbers_solution

(vector<

int> input,

int k)};

#endif

利用堆排序,特別適用於海量資料中尋找最大或者最小的k個數字。即構建乙個大堆容器,初始化大小為k,變數初始數,如初始陣列大小小於等於k直接返回,如果大於k,則選擇陣列的前k個元素,填充堆,然後調整為最大堆。調整完之後,繼續從初始陣列中拿出乙個元素,如果該元素比大堆的堆頂小,則替換堆頂,繼續調整為最大堆,如果大於等於堆頂則直接丟棄,不作調整。

ps:大堆還是小堆的選擇很重要,不是尋找最小的k個元素就要選擇小堆,而且恰恰相反。尋找最小的k個數,其實就是尋找第k個大的元素,即尋找k個數中最大的,不斷調整堆,堆得元素個數是k,堆頂是最大值,遍歷完初始陣列後,堆中存在的元素即使我們所要尋找的k個最小元素。

最大的k個數---- 建小堆

最小的k個數----建大堆

//方法三:堆

//用最大堆儲存這k個數,每次只和堆頂比,如果比堆頂小,刪除堆頂,新數入堆。

#if 1

class

solution

} result.

assign

(input.

begin()

, input.

begin()

+ k)

;return result;

}#if 0

void

adjustheap

(vector<

int>

&input,

int i,

int length)}}

#elif 1

//根節點序號為0開始的堆排序

void

adjustheap

(vector<

int>

&input,

int k,

int len)

} input[k]

= temp;

}#endif};

#endif

/*//堆排序流程

void heapsort(vector&input, int length)

for(int i = length-1; i >= 0; i--)

}};*/

20200910

class

solution

} res.

assign

(arr.

begin()

,arr.

begin()

+k);

return res;

}void

adjustdown

(vector<

int>

&a,int len,

int k )

//k當前待調整的節點

else

break;}

a[k]

= temp;}}

;

也可以直接使用stl實現中的堆排序,stl中並沒有實現堆這種資料結構,但是algorithm中實現了堆排序演算法。主要就是四個函式,make_heap(),pop_heap(),push_heap(),sort_heap()。

make_heap

(first ,last)

make_heap

(first ,last, cmpobject)

將[ first, last )範圍進行堆排序,預設使用less < int>, 即 :最大元素放在第乙個。

pop_heap

(first ,last)

pop_heap

(first ,last, cmpobject)

將front(即第乙個最大元素)移動到end的前部,同時將剩下的元素重新構造成(堆排序)乙個新的heap

push_heap

(first ,last)

push_heap

(first ,last, cmpobject)

對剛插入的尾部元素做堆排序。

sort_heap

(first ,last)

sort_heap

(first ,last, cmpobject)

將乙個堆做排序,最終成為乙個有序的系列,可以看到sort_heap時,必須先是乙個堆(兩個特性:1、最大元素在第乙個 2、新增或者刪除元素以對數時間),因此必須先做一次make_heap.

//20200308,堆stl

class

solution

//建堆

make_heap

(res.

begin()

, res.

end())

;//第三個引數預設為less<>(),即大根堆

for(

int i = k; i < input.

size()

;++i)

}return res;}}

;

class

solution

}for

(int i =

0; i < k;

++i)

return res;}}

;

通過assign進行賦值時,目標vector之前可為空,如果通過元素乙個個賦值,則應該先初始化目標vector,或通過resize申請空間,或者使用push_back壓入元素

方法二和方法三優缺點:比較

思路2優點:節省空降,時間複雜度平均為o(n)

缺點:需要修改原始陣列

思路3優點:不用修改原始陣列,適合海量資料

缺點:時間複雜度略高o(nlogk)

面試題40 最小k個數

題目 輸入n個整數,找出其中最小的k個數 思路 1 如果輸入的陣列可以改變,則基於第k個數來調整,是第k個數左邊的數都小於第k個數,右邊的數都大於第k個數 時間複雜度o n 思路1 void printkminnumberbymethod1 int arr,int length,int k int ...

面試題40 最小的K個數

輸入n個整數,找出其中最小的k個數。例如輸入4 5 1 6 2 7 3 8 這8個數字,則最小的4個數字是1 2 3 4。分析 這道題最簡單的思路莫過於把輸入的n個整數排序,排序之後位於最前面的k個數就是最小的k個數,這種思路的時間按複雜度是o nlogn 2.1 方法一 時間複雜度為o n 的演算...

面試題40 最小的K個數

題目描述 輸入n個整數,找出其中最小的k個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,方法一 不修改原陣列,時間複雜度o nlgk class solution if result k 1 input i result k 1 input i return...