网上看到了一道关于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最频繁变动的股价的更多相关文章

  1. WeQuant交易策略—MACD

    MACD(指数平滑异同平均线)策略简介MACD指标应该是大家最常见的技术指标,在很多股票.比特币的软件中都是默认显示的.MACD是从双指数移动平均线发展而来的.意义和双移动平均线基本相同,即由快.慢均 ...

  2. Redis 与 数据库处理数据的两种模式

    Redis 是一个高性能的key-value数据库. redis的出现,很大程度补偿了memcached这类key-value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用.它提供了Pyt ...

  3. nuget国内镜像的解决办法

    不求人,在阿里云上安一个nuget镜像站,这样就能愉快编程了. 主要是利用nginx 的反向代理+缓存功能+响应文本的替换 proxy_cache_path /data/nuget-cache lev ...

  4. TDD学习笔记【二】---单元测试简介

    大纲 Testing 的第一个切入点:单元测试. 本篇文章将针对单元测试进行简介,主要内容包含了5W: Why What Where Who When 而How 的部分,属于实现部分,将于下一篇文章介 ...

  5. 常见linux命令释义(第八天)—— Bash Shell 的操作环境

    换了新公司,公司的领导很不错.自己感受比较多的地方是,自己的工作效率明显比以前高了.以前会对频繁变动的需求十分不耐烦,现在接到需求后会仔细的思考,进行整体构建.即使以后需求有变动,也能够比较轻易的在原 ...

  6. DataTable数据检索的性能分析(转寒江独钓)

    我们知道在.NET平台上有很多种数据存储,检索解决方案-ADO.NET Entity Framework,ASP.NET Dynamic Data,XML, NHibernate,LINQ to SQ ...

  7. C# 依赖注入

      http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html 这篇文章真的非常非常好···绝对值得收藏学习.     目录 目录 1 ...

  8. 使用IronPython给.Net程序加点料

    开发的时候,经常被策划频繁变动的方案而苦恼.这时候就想要加入点动态语言来辅助一下. 在考虑用动态语言之前也曾想过使用动态加载dll的方式,实现基础接口来调用.在卸载的时候遇到了问题,虽可以通过应用程序 ...

  9. ReactMix框架,让你实现一套js代码,基于ReactNative在H5,App都能完美跑起来,Write Once,Run Anywhere

    ReactNative框架推出已经有一段时间了,相信很多小伙伴都在尝试实现Write Once, Run Anywhere的梦想,比如淘宝的ReactWeb等等,但是这些框架都局限于因为ReactNa ...

随机推荐

  1. Synchronized使用方法

    Synchronized是我们常用来维持线程安全时使用的一个关键字,内部通过monitor(监视器锁,由C++实现)来实现.而monitor本质又是依赖底层操作系统的mutex lock来实现.而操作 ...

  2. 629D - Babaei and Birthday Cake

    题意:给定n个圆柱体的半径和高,输入顺序即圆柱体的编号顺序.现在规定,只有编号和体积均大于另一个圆柱体,才能放到另一个圆柱体的体积上面.求能叠加的最大体积是多少. 酝酿了我三天,才理解.自己敲个代码, ...

  3. 【NOIP2015普及组】推销员_详解

    题目 题目大意 阿明是一名推销员--螺丝街是一条直线,一端有入口,一共有 \(N(<100,000)\) 家住户,第 \(i\) 家住户到入口的距离为 \(S_i\) 米.由于同一栋房子里可以有 ...

  4. company_credit

    /** * Created by wu-yj on 2016/5/6. */ import java.sql.{Connection, DriverManager, PreparedStatement ...

  5. Python 使用有道翻译

    最近想将一些句子翻译成不同的语言,最开始想使用Python向有道发送请求包的方式进行翻译. 这种翻译方式可行,不过只能翻译默认语言,不能选定语言,于是我研究了一下如何构造请求参数,其中有两个参数最复杂 ...

  6. SQL Server同一表不同列数据同步

    直接上脚本 update table set a=b where a=xxx table==表名称 a==需要同步的列 b==数据源列,就是a列要的数据是b列的数据 where 条件.不加where则 ...

  7. ssh 框架整合事,使用注解,action提示找不到

    There is no Action mapped for namespace [/] and action name [/select] associated with context path [ ...

  8. ArcGIS Pro开发Web3D应用(4)——Portal发布三维没有“发布”选项解决

    如题,将三维场景包.slpk上传并发布,未看到发布选项. 问题核心就在于环境没配置好,主要有2点: 1.验证联合托管状态 需要将托管服务器与Portal进行联合,并进行验证,此情况需要在WebAdap ...

  9. shell 获得后台进程返回值

    获得后台进程返回值我们用“&”把进程放入后台以后,如果需要了解进程的执行情况,可以使用wait函数.默认情况下wait会等待任意子进程结束但是不会返回子进程的返回值.而以子进程的pid作为参数 ...

  10. leecode第二百九十二题(Nim游戏)

    class Solution { public: bool canWinNim(int n) { )==)//用与的时候,要注意优先级问题 //用n%4==0的时候,其耗时比用&短,但是空间消 ...