28 最小的K个数
题目描述
class Solution {
public:
int partition(vector<int> &input,int lo,int hi){
int pos = lo + rand() % (hi - lo + );
int pivot = input[pos];
swap(input[lo],input[pos]);
while(lo < hi){
while(lo < hi){
if(input[hi] > pivot){
--hi;
}
else{
input[lo] = input[hi];
++lo;
break;
}
}
while(lo < hi){
if(input[lo] < pivot){
++lo;
}
else{
input[hi] = input[lo];
--hi;
break;
}
}
}
input[lo] = pivot;
return lo;
}
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
if(input.empty() || k > input.size() || k <= ){
return {};
}
vector<int> result;
int lo = ,hi = input.size() - ;
int idx ;
idx = partition(input,lo,hi);//
int target = k - ;
while(idx != target){
if(idx < target){
lo = idx + ;
}
else if(idx > target){
hi = idx - ;
}
idx = partition(input,lo,hi);
}
for(int i = ;i < k;++i){
result.push_back(input[i]);
}
return result;
}
};
第二种方法:
解法2:O(nlogk)的算法,特别适合处理海量数据。
priority_queue加入和删除操作都是O(logk),top操作是O(1)。默认top的是最大元素。优先级队列本质是基于vector实现的最大堆,因为vector通过下标访问数组,所以top操作复杂度是O(1)的;
STL的set和map还有就是multise和multimap都是基于红黑树实现的,begin是最小元素,即基于最小堆实现的,只有自己写一个仿函数就可以得到最大堆,注意就重载()就行了,stack和queue都是基于deque。红黑树中查找、删除和插入操作的时间复杂度都是O(logk)。
如果要使用仿函数要引入头文件functional。才可以使用greater<int>。
但它是如何保证一棵n个结点的红黑树的高度始终保持在logn的呢?这就引出了红黑树的5个性质:
- 每个结点要么是红的要么是黑的。
- 根结点是黑的。
- 每个叶结点(叶结点即指树尾端NIL指针或NULL结点)都是黑的。
- 如果一个结点是红的,那么它的两个儿子都是黑的。
- 对于任意结点而言,其到叶结点树尾端NIL指针的每条路径都包含相同数目的黑结点。
#include<iostream>
#include<vector>
#include<string>
#include <cstdio>
#include<queue>
#include<algorithm>
#include<set>
using namespace std;
template<typename T>
struct greater{
bool operator() (const T &a, const T &b) {
return a > b;
}
}; int main() {
multiset<int,greater<int>> hashSet;
for (int i = ; i < ; ++i) {//输入1,3,55,4
int a = ;
cin >> a;
hashSet.insert(a);
}
multiset<int>::iterator iter = hashSet.begin();//得到55
cout << *iter << endl;
system("pause");
}
仿函数最大set
#include<iostream>
#include<vector>
#include<set>
#include<functional>
using namespace std;
int main() {
multiset<int,greater<int>> hashSet;
for (int i = ; i < ; ++i) {//输入1,3,55,4
int a = ;
cin >> a;
hashSet.insert(a);
}
multiset<int>::iterator iter = hashSet.begin();//得到55
cout << *iter << endl;
system("pause");
}
使用functional
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> result;
if(input.empty() || k <= || k > input.size()){
return result;
}
multiset<int,greater<int>> hashSet;
multiset<int,greater<int>>::iterator iter = hashSet.begin();
for(int i = ;i < input.size();++i){
iter = hashSet.begin();
if(hashSet.size() < k){
hashSet.insert(input[i]);
}
else{
if(*iter > input[i]){
hashSet.erase(*iter);
hashSet.insert(input[i]);
}
}
}
iter = hashSet.begin();
for(iter;iter != hashSet.end();++iter){
result.push_back(*iter);
}
return result;
}
};
解法3:
使用priority_queue实现最大堆。(默认是最大堆,即top等于最大的元素,降序);
底层容器是vector实现的最大堆(stl源码)
模板:priority_queue<int,vector<int>,greater<int>>,升序,最小堆
class Solution {
public:
vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
vector<int> result;
if(input.empty() || k <= || k > input.size()){
return result;
}
priority_queue<int> q;
for(int i = ;i < input.size();++i){
if(q.size() < k){
q.push(input[i]);
}
else{
if(q.top() > input[i]){
q.pop();
q.push(input[i]);
}
}
}
for(int i = ;i < k;++i){
result.push_back(q.top());
q.pop();
}
return result;
}
};
28 最小的K个数的更多相关文章
- 【面试题030】最小的k个数
[面试题030]最小的k个数 题目: 输入n个整数,找出其中最小的k个数. 例如输入4.5.1.6.2.7.3.8这8个字,则其中最小的4个数字是1.2.3.4. 思路一: ...
- 29.最小的K个数
题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 思路分析: 利用快速排序的partition函数,par ...
- 剑指Offer面试题:27.最小的k个数
一.题目:最小的k个数 题目:输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 这道题是典型的TopK问题,其最简单的思路莫过于 ...
- 算法练习:寻找最小的k个数
参考July的文章:http://blog.csdn.net/v_JULY_v/article/details/6370650 寻找最小的k个数题目描述:查找最小的k个元素题目:输入n个整数,输出其中 ...
- 剑指Offer:面试题30——最小的k个数(java实现)
问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...
- 输入一个数组,求最小的K个数
被这道题困了好久,看了剑指Offer才知道OJ上的要求有点迷惑性. 题目: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4. 一 ...
- 1046: 最小的K个数
1046: 最小的K个数 时间限制: 1 Sec 内存限制: 128 MB提交: 233 解决: 200[提交][状态][讨论版] 题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1 ...
- 最小的K个数:用快排的思想去解相关问题
实现快速排序算法的关键在于先在数组中选择一个数字,接下来把数组中的数字分为两部分,比选择的数字小的数字移到数组的左边,比选择的数字大的数字移到数组的右边. 这个函数可以如下实现: int Partit ...
- 剑指offer面试题30:最小的k个数
一.题目描述 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,. 二.解题思路 1.思路1 首先对数组进行排序,然后取出前k个数 ...
随机推荐
- JS中 逻辑或 || 逻辑与 && 的使用方法总结
JS中 逻辑或 || 逻辑与 && 的使用方法总结 //1.在if判断中 //if(1==1 || 2==3){}//->两个条件中只要有一个条件为真,整体就为真 "或 ...
- Django框架之ORM对表结构操作
ORM的优点:(1)简单,不用自己写SQL语句 (2)开发效率高 ORM的缺点:对于不同的人写的代码,执行效率有差别 ORM的对应关系: 类 ----------> 数据表 对象------ ...
- javascript的正则匹配
前段时间需要用到比较多的js代码,当时有点搞不清test和match方法的区别,向百度求助,找到了这边关于正则匹配的博文,感谢作者分享. 原文地址[http://blog.sina.com.cn/s/ ...
- 201771010135杨蓉庆《面向对象程序设计(java)》第二周学习总结
第一部分:理论知识学习部分 3.1 标识符:由字母.下划线.美元符号和数字组成, 且第一个符号不能为数字,可用作:类名.变量名.方法名.数组名.文件名等.有Hello.$1234.程序名.www_12 ...
- Spring Boot JDBC 使用教程
总是要用到数据库的嘛,曾经我一度以为,写代码,编程就是搞数据库增删改查,甚至你设计一个系统,大部分时候在为如何设计关系型数据库努力,究其原因,是因为关系型数据库是逻辑的主要呈现. 这个系列,主要是对 ...
- 吴裕雄--天生自然Numpy库学习笔记:NumPy 迭代数组
import numpy as np a = np.arange(6).reshape(2,3) print ('原始数组是:') print (a) print ('\n') print ('迭代输 ...
- 吴裕雄--天生自然TensorFlow2教程:反向传播算法
- jQuery结合CSS实现手风琴组件(2)----利用seajs实现静态资源模块化引入
1. 目录结构(webStrom) 2. 代码 1.html <!DOCTYPE html> <html lang="en"> <head> & ...
- LeetCode 234. Palindrome Linked List(判断是否为回文链表)
题意:判断是否为回文链表,要求时间复杂度O(n),空间复杂度O(1). 分析: (1)利用快慢指针找到链表的中心 (2)进行步骤(1)的过程中,对前半部分链表进行反转 (3)如果链表长是偶数,首先比较 ...
- codeforces- Shortest path of the king
The king is left alone on the chessboard. In spite of this loneliness, he doesn't lose heart, becaus ...