topk算法
方法一 堆排序
自建堆 heapMax方法,从上至下调整堆
pop时,可以使用自上而下调整堆,调用heapMax(arr,0,sz-1);
push时,需要自下到上调整即
从上到下调整:
void heapDown(vector<int>& arr,int start,int end)
{
int dad = start;
int son = 2 * dad + 1;
while(son<=end) //可以取到end
{
if(son+1<=end && arr[son]<arr[son+1]) ++son;
if(arr[son]<arr[dad]) return;
else
{
swap(arr[son],arr[dad]);
dad = son;
son = 2 * dad + 1;
}
}
}
从下到上:
```cpp
//从下到上调
int son = sz-1;
int dad = (son-1)/2;
while(dad>=0)
{
if(arr[son]<=arr[dad]) return;
else
{
swap(arr[son],arr[dad]);
son = dad;
dad = (son-1)/2;
}
}
```
建堆
for(int i=(len/2)-1;i>=0;--i)
{
heapDwon(heap,i,len-1);
}
堆代码
class Solution {
public:
//堆排序 从0 开始
void heapDown(vector<int>& arr,int start,int end)
{
int dad = start;
int son = 2 * dad + 1;
while(son<=end) //可以取到end
{
if(son+1<=end && arr[son]<arr[son+1]) ++son;
if(arr[son]<arr[dad]) return;
else
{
swap(arr[son],arr[dad]);
dad = son;
son = 2 * dad + 1;
}
}
}
void push(vector<int>& arr,int val)
{
arr.push_back(val);
int sz = arr.size();
//从下到上调
int son = sz-1;
int dad = (son-1)/2;
while(dad>=0)
{
if(arr[son]<=arr[dad]) return;
else
{
swap(arr[son],arr[dad]);
son = dad;
dad = (son-1)/2;
}
}
}
void pop(vector<int>& arr)
{
swap(arr[0],arr[arr.size()-1]);
arr.pop_back();
int sz = arr.size();
heapMax(arr,0,sz-1);
}
vector<int> smallestK(vector<int>& arr, int k) {
//堆
// priority_queue<int,vector<int>,less<int>> heap; //大顶堆
// //priority_queue<int,vector<int>,greater<int>> c;
//自定义堆
if(k==0) return {};
vector<int> heap(k);
for(int i=0;i<k;++i)
{
heap[i] = arr[i];
}
for(int i=k/2-1;i>=0;--i)
{
heapMax(heap,i,k-1);
}
for(int i=k;i<arr.size();++i)
{
if(arr[i]<heap[0])
{
pop(heap);
push(heap,arr[i]);
}
}
return heap;
}
};
方法二:快排思维(平均时间复杂度O(n)) topk思路
partition函数负责每次找到pivot,并分为2段
//加入随机思路
int randIndex = rand(time) % ((right-left+1)+left);
swap(arr[randIndex],arr[right]);
int pivot = arr[right];
判断条件:
1. k-1<p 说明k在p左边,因此递归查找左边
2. k-1>p 说明k在p右边,因此递归查找左边
3. k-1==p ,说明找到第k大,即左边为k个最小的元素
```cpp
//快排
int partition(vector<int>& arr,int left,int right)
{
int i = left,j=left;
int randIndex = rand(time) %((right - left + 1) + left); //长度加left
swap(arr[randIndex],arr[right]);
int pivot = arr[right];
for(;j<right;++j)
{
if(arr[j]<pivot)
{
swap(arr[i],arr[j]);
++i;
}
}
swap(arr[i],arr[right]);
return i;
}
void helper(vector<int>& arr, int k,int left,int right,vector<int>& res)
{
if(left>right) return;
int p = partition(arr,left,right);
if(k-1==p) //find k
{
for(int i=0;i<k;++i)
{
res.push_back(arr[i]);
}
}
else if(k-1<p)
{
helper(arr,k,left,p-1,res);
}
else
{
helper(arr,k,p+1,right,res);
}
return;
}
```
topk算法的更多相关文章
- 关于堆排序和topK算法的PHP实现
问题描述 topK算法,简而言之,就是求n个数据里的前m大个数据,一般而言,m<<n,也就是说,n可能有几千万,而m只是10或者20这样的两位数. 思路 最简单的思路,当然是使用要先对这n ...
- java TopK算法
现有一亿个数据,要求从其中找出最小的一万个数,希望所需的时间和空间最小,也就是所谓的topK问题 TopK问题就是从海量的数据中取最大(或最小的)的K个数. TopK问题其实是有线性时间复杂度的解的, ...
- (转)基于快速排序的TOPK算法
基于快速排序的TOPK算法 转自:http://blog.csdn.net/fanzitao/article/details/7617223 思想: 类似于快速排序,首先选择一个划分元,如果这个划分元 ...
- topK 算法
搜索引擎热门查询统计 题目描述: 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节. 假设目前有一千万个记录(这些查询串的重复度比较高,虽然 ...
- Python 实现转堆排序算法原理及时间复杂度(多图解释)
原创文章出自公众号:「码农富哥」,欢迎转载和关注,如转载请注明出处! 堆基本概念 堆排序是一个很重要的排序算法,它是高效率的排序算法,复杂度是O(nlogn),堆排序不仅是面试进场考的重点,而且在很多 ...
- 大数据热点问题TOP K
1单节点上的topK (1)批量数据 数据结构:HashMap, PriorityQueue 步骤:(1)数据预处理:遍历整个数据集,hash表记录词频 (2)构建最小堆:最小堆只存k个数据. 时间复 ...
- 大数据计算:如何仅用1.5KB内存为十亿对象计数
大数据计算:如何仅用1.5KB内存为十亿对象计数 Big Data Counting: How To Count A Billion Distinct Objects Using Only 1.5K ...
- HashTable和HashSet中的类型陷阱
HashTable和HashSet中的类型陷阱 发现这个陷阱的起因是这样的:我现在有上百万字符串,我准备用TopK算法统计出出现次数做多的前100个字符串. 首先我用Hashtable统计出了每个字符 ...
- sdn测量论文简介
Prelude: Ensuring Inter-Domain Loop-Freedom in SDN-Enabled Networks 来源:APNet: The Asia-Pacific Works ...
随机推荐
- JavaScript 原生控制元素添加删除
参考: https://blog.csdn.net/leijie0322/article/details/80664554 https://www.cnblogs.com/jpfss/p/910620 ...
- IdentityServer4系列[6]授权码模式
授权码模式是一种混合模式,是目前功能最完整.流程最严密的授权模式.它主要分为两大步骤:认证和授权.其流程为: 用户访问客户端,客户端将用户导向Identity Server. 用户填写凭证信息向客户端 ...
- windows环境下配置Kafaka
一.安装Zookeeper(Kafaka依赖于zookeeper进行服务注册和管理) 1. 1 下载zookeeper:http://mirror.bit.edu.cn/apache/zookee ...
- VS运行时 /MD、/MDd 和 /MT、/MTd之间的区别
程序运行时出现问题,选择的是Release,win64位的模式,并且已经看到了宏定义NDEBUG,但是程序依然进入上面的部分 解决方案是将属性->C/C++->代码生成器->运行库里 ...
- JVM堆内存泄露分析
一.背景 公司有一个中间的系统A可以对接多个后端业务系统B,一个业务系统以一个Namespace代表, Namespace中包含多个FrameChannel(用holder保存),表示A连接到业务 ...
- 洛谷3288 SCOI2014方伯伯运椰子(分数规划+spfa)
纪念博客又一次爆炸了 首先,对于本题中,我们可以发现,保证存在正整数解,就表示一定费用会降低.又因为一旦加大的流量,费用一定会变大,所以总流量一定是不变的 那么我们这时候就需要考虑一个退流的过程 对于 ...
- Windows用cmd编译运行Java程序
https://www.runoob.com/w3cnote/windows10-java-setup.html
- Upload-labs通关指南(上) 1-10
Upload-labs 所有文章和随笔(随笔将不于csdn更新)将于我的个人博客(移动端暂未适配)第一时间更新. 一些网站存在文件上传接口,一旦存在这个接口就有可能存在漏洞. 文件上传漏洞的逻辑是将一 ...
- Apache Common-collection 反序列化利用链解析--TransformedMap链
Apache Common-collection 反序列化利用链解析 TransformedMap链 参考Java反序列化漏洞分析 - ssooking - 博客园 (cnblogs.com) poc ...
- NX 图标
vector_on_curve crosscut_zig_zag_with_lifts vector_along_curve zlevel_zig add_new_sc zlevel_zi ...