《劍指offer》刷題筆記(時間效率):最小的K個數
- 轉載請注明作者和出處:http://blog.csdn.net/u011475210
- 代碼位址:https://github.com/WordZzzz/Note/tree/master/AtOffer
- 刷題平台:https://www.nowcoder.com/
- 題 庫:劍指offer
- 編 者:WordZzzz
- 劍指offer刷題筆記時間效率最小的K個數
- 題目描述
- 解題思路
- C版代碼實作
- 思路一
- 最大堆
- 紅黑樹
- Python版代碼實作
- 思路一
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
解題思路
思路一:結合快排。排序後直接for循環将最小的K個數填入結果。時間複雜度O(NlogK)。
思路二:最大堆或者紅黑樹。我們可以先建立一個大小為K的資料容器來存儲最小的k個數字,然後每次從N個整數中讀取一個數。如果容器中已有的數字個數少于K,則直接把這次讀入的整數放入容器中;如果容器中已經有K個數了,此時我們需要找出容器中的最大值,然後與待插入的整數進行比較,誰小就留着誰。
我們再來捋一遍,容器滿了之後我們要做的三件事情:一是在k個證書中找到最大數;二是有可能在這個容器中删除最大數;三是有可能要插入一個新的數字。如果用一個二叉樹來實作這個資料容器,那麼我們能在O(logK)時間内實作這三步操作。是以對于N個輸入數字而言,總時間效率就是O(Nlogk)。
最大堆:根結點的值總是大于它的子樹中任意結點的值。我們需要O(1)時間得到最大值,O(logK)時間來完成删除及插入操作;
紅黑樹:根據一定規則確定樹在一定程度上是平衡的,進而保證在紅黑樹種查找、删除和插入操作都隻需要O(logK)時間。
Python中沒有現成的最大堆或者紅黑樹實作,本渣渣就不再這裡折騰了。
C++版代碼實作
思路一
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> res;
if(input.empty() || k > input.size())
return res;
sort(input.begin(), input.end());
for(int i = ; i < k; ++i)
res.push_back(input[i]);
return res;
}
};
最大堆
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int len = input.size();
if(len <= || k > len || k <= )
return vector<int>();
vector<int> res(input.begin(), input.begin()+k);
//建堆
make_heap(res.begin(), res.end());
for(int i=k; i < len; i++)
{
if(input[i] < res[])
{
//先pop,然後在容器中删除
pop_heap(res.begin(), res.end());
res.pop_back();
//先在容器中加入,再push
res.push_back(input[i]);
push_heap(res.begin(), res.end());
}
}
//使其從小到大輸出
sort_heap(res.begin(), res.end());
return res;
}
};
紅黑樹
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
int len = input.size();
if(len <= || k > len || k <= )
return vector<int>();
//仿函數中的greater<T>模闆,從大到小排序
multiset<int, greater<int> > leastNums;
vector<int>::iterator vec_it = input.begin();
for(; vec_it != input.end(); vec_it++)
{
//将前k個元素插入集合
if(leastNums.size() < k)
leastNums.insert(*vec_it);
else
{
//第一個元素是最大值
multiset<int, greater<int> >::iterator greatest_it = leastNums.begin();
//如果後續元素<第一個元素,删除第一個,加入目前元素
if(*vec_it < *(leastNums.begin()))
{
leastNums.erase(greatest_it);
leastNums.insert(*vec_it);
}
}
}
return vector<int>(leastNums.begin(), leastNums.end());
}
};
Python版代碼實作
思路一
# -*- coding:utf-8 -*-
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
if tinput is None:
return
n = len(tinput)
if n < k:
return []
tinput = sorted(tinput)
return tinput[:k]
系列教程持續釋出中,歡迎訂閱、關注、收藏、評論、點贊哦~~( ̄▽ ̄~)~
完的汪(∪。∪)。。。zzz