实时输出topk最频繁变动的股价
网上看到了一道关于bloomburg的面试题,follow 评论的思路 自己试着写了一个HashHeap的实现。
基本思路是维护一个大小为K的最小堆,里面是topK股价变动的公司ID(假设ID是Integer)
HashHeap中维护一个companyIdHeap 之外还有一个HashMap 它的key 是CompanyId, value是Company信息 此处我假设company信息包含这个company在companyIdHeap中的index (这个index可以使delete function的复杂度降到O(logK))和它的股价变化了多少次
每当有新的估价更新,假设应用会调用HashHeap的add函数 输入是当前股价变化的公司ID 然后更新 hashmap 和 根据当前heap size更新companyIdHeap
在更新companyIdHeap的时候 如果这个变化的公司的股价变化次数大于最小堆的root 那么替换掉这个root 然后从0向下调整heap heap调整的比较条件是看谁的股价变化次数少
delete函数直接delete掉一个company O(logK)
poll函数是给heap root的company的股价变化次数减一(其实还没想好这个函数具体应该做什么 暂时把它放在注释里面)
不足之处请指出! 多谢!
package Heap; import java.util.*; public class HashHeap {
//a list of companyId
private List<Integer> companyIdHeap;
private int size_t;
//map from companyId to Node {index in heap and frequent}
private Map<Integer, Node> companyToFrequent;
private String mode; //min or max
private int K;
class Node{
public int index;
public int frequent;
public Node (int index, int fre){
this.index= index;
this.frequent = fre;
}
public Node(Node node){
this.index = node.index;
this.frequent = node.frequent;
}
} public HashHeap(int K){
this.companyIdHeap = new ArrayList<Integer>();
this.size_t =0;
this.companyToFrequent = new HashMap<Integer, Node>();
mode = "min";
this.K = K;
} public int peek(){
if(!companyIdHeap.isEmpty())
return companyIdHeap.get(0);
return -1;
} public int size(){
return size_t;
} public boolean empty(){
return companyIdHeap.size()==0;
} public int parent(int id){
if(id==0){
return -1;
}
return (id-1)/2;
} public int lson(int id){
return 2*id +1;
} public int rson(int id){
return 2*id+2;
} public boolean compare(int companyA, int companyB){
if(companyToFrequent.get(companyA).frequent<companyToFrequent.get(companyB).frequent){
if(mode.equals("min")){
return true;
}else{
return false;
}
}else{
if(mode.equals("min")){
return false;
}else{
return true;
}
}
} public void swap(int indexA, int indexB){
int companyA = companyIdHeap.get(indexA);
int companyB = companyIdHeap.get(indexB);
Node compNodeA = companyToFrequent.get(companyA);
Node compNodeB = companyToFrequent.get(companyB);
companyIdHeap.set(indexA, companyB);
companyIdHeap.set(indexB, companyA);
companyToFrequent.put(companyA, new Node(indexB, compNodeA.frequent));
companyToFrequent.put(companyB, new Node(indexA, compNodeB.frequent));
} public void siftup(int index){
while(parent(index)>-1){
int parent = parent(index);
if(compare(companyIdHeap.get(parent), companyIdHeap.get(index))){
break;
}else{
swap(parent, index);
}
index = parent;
}
} public void siftdown(int index){
while(lson(index)< companyIdHeap.size()){
int leftSon = lson(index);
int rightSon = rson(index);
int son = rightSon;
if(rightSon>=companyIdHeap.size()||compare(companyIdHeap.get(leftSon),companyIdHeap.get(rightSon))){
son = leftSon;
}
if(compare(companyIdHeap.get(index), companyIdHeap.get(son))){
break;
}else{
swap(index, son);
}
index=son;
} } public void add(int company){
//update hashmap
if(companyToFrequent.containsKey(company)){
Node node = companyToFrequent.get(company);
companyToFrequent.put(company, new Node(node.index, node.frequent+1));
}else{
companyToFrequent.put(company, new Node(-1, 1));
}
//update heap
Node node = companyToFrequent.get(company);
if(this.size_t==K){
//if heap need to be updated
if(compare(peek(), company)){
companyIdHeap.set(0, company);
companyToFrequent.put(company, new Node(0, node.frequent));
siftdown(0);
}
return;
}
companyIdHeap.add(company);
size_t++;
companyToFrequent.put(company, new Node(companyIdHeap.size()-1, node.frequent));
siftup(companyIdHeap.size()-1);
} public void delete(int company){
if(companyToFrequent.containsKey(company)){
Node node = companyToFrequent.get(company);
int index = node.index;
swap(index, companyIdHeap.size()-1);
companyIdHeap.remove(companyIdHeap.size()-1);
companyToFrequent.remove(company);
size_t--;
//the condition will be false if index == companyIdHeap.size()-1 before
if(index<companyIdHeap.size()){
siftup(index);
siftdown(index);
}
}
} /*public int poll(){
int res = companyIdHeap.get(0);
Node node = companyToFrequent.get(res);
if(node.frequent==1){
size_t--;
swap(0, companyIdHeap.size()-1);
companyIdHeap.remove(companyIdHeap.size()-1);
companyToFrequent.remove(res);
// the condition will be true is companyIdHeap.size() == 1 before
if(companyIdHeap.size()>0){
siftdown(0);
}
}else{
companyToFrequent.put(res, new Node(0, node.frequent-1));
} return res;
}*/
}
实时输出topk最频繁变动的股价的更多相关文章
- WeQuant交易策略—MACD
MACD(指数平滑异同平均线)策略简介MACD指标应该是大家最常见的技术指标,在很多股票.比特币的软件中都是默认显示的.MACD是从双指数移动平均线发展而来的.意义和双移动平均线基本相同,即由快.慢均 ...
- Redis 与 数据库处理数据的两种模式
Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key-value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了Pyt ...
- nuget国内镜像的解决办法
不求人,在阿里云上安一个nuget镜像站,这样就能愉快编程了. 主要是利用nginx 的反向代理+缓存功能+响应文本的替换 proxy_cache_path /data/nuget-cache lev ...
- TDD学习笔记【二】---单元测试简介
大纲 Testing 的第一个切入点:单元测试. 本篇文章将针对单元测试进行简介,主要内容包含了5W: Why What Where Who When 而How 的部分,属于实现部分,将于下一篇文章介 ...
- 常见linux命令释义(第八天)—— Bash Shell 的操作环境
换了新公司,公司的领导很不错.自己感受比较多的地方是,自己的工作效率明显比以前高了.以前会对频繁变动的需求十分不耐烦,现在接到需求后会仔细的思考,进行整体构建.即使以后需求有变动,也能够比较轻易的在原 ...
- DataTable数据检索的性能分析(转寒江独钓)
我们知道在.NET平台上有很多种数据存储,检索解决方案-ADO.NET Entity Framework,ASP.NET Dynamic Data,XML, NHibernate,LINQ to SQ ...
- C# 依赖注入
http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html 这篇文章真的非常非常好···绝对值得收藏学习. 目录 目录 1 ...
- 使用IronPython给.Net程序加点料
开发的时候,经常被策划频繁变动的方案而苦恼.这时候就想要加入点动态语言来辅助一下. 在考虑用动态语言之前也曾想过使用动态加载dll的方式,实现基础接口来调用.在卸载的时候遇到了问题,虽可以通过应用程序 ...
- ReactMix框架,让你实现一套js代码,基于ReactNative在H5,App都能完美跑起来,Write Once,Run Anywhere
ReactNative框架推出已经有一段时间了,相信很多小伙伴都在尝试实现Write Once, Run Anywhere的梦想,比如淘宝的ReactWeb等等,但是这些框架都局限于因为ReactNa ...
随机推荐
- MAVEN项目中include引入静态文件时报错找不到文件
1. 出现的问题 Fragment "/common/jsp/resource.jsp" was not found at expected path /src/main/weba ...
- vector某元素是否存在、查找指定元素 、去重
vector.map 判断某元素是否存在.查找指定元素 [C++]判断元素是否在vector中,对vector去重,两个vector求交集.并集 PS:注意重载
- Python内置进制转换函数(实现16进制和ASCII转换)
在进行wireshark抓包时你会发现底端窗口报文内容左边是十六进制数字,右边是每两个十六进制转换的ASCII字符,这里使用Python代码实现一个十六进制和ASCII的转换方法. hex() 转换一 ...
- 新的尝试!ComponentOne WinForm 和 .NET Core 3.0
在微软 Build 2018 开发者大会上,.NET 团队公布了 .NET Core 的下一个主要版本 .NET Core 3.0 的规划蓝图:.NET Core 3将开始支持Windows桌面应用程 ...
- canvas连线特效
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 数据库连接超时:“The last packet successfully received from the server was xxx milliseconds ago”
产生的原因:应用方的数据库连接有效期时间,大于数据库自己设置的有效期. 解决方案: 一.修改druid配置(如果使用druid的话) spring.datasource.druid.validatio ...
- Redis 持久化RDB 和AOF
一.持久化之全量写入:RDB rdb配置 [redis@6381]$ more redis.conf save 900 1 save 300 10 save 60 10000 dbfilename & ...
- 雷林鹏分享:Laravel 安装
前面我们介绍我了 composer安装,这里我们接着来介绍 Laravel框架的安装. 这里我们安装的是laravel 4 项目下载地址:https://github.com/laravel/lara ...
- 实用的shell脚本面试题和答案
1. 写一个shell脚本来得到当前的日期,时间,用户名和当前工作目录. 答案 : 输出用户名,当前日期和时间,以及当前工作目录的命令就是logname,date,who i am和pwd. 现在,创 ...
- PCA和PCoA
讲解很详细:http://blog.genesino.com/2016/10/PCA/ PCA分析一般流程: 中心化(centering, 均值中心化,或者中位数中心化),定标(scale,如果数据没 ...