实时输出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 ...
随机推荐
- Java基础学习-流程控制语句
在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说程序的流程对运行结果有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要通过控制语句的执行顺序来实现我 ...
- node一些相关
1.Node node的核心语言是JavaScript ,基于Google的V8引擎. 2.node使用 找到当前文件所在目录 node 文件名.js 直接用绝对路径 在当前目录打开命令窗口 3.n ...
- Lintcode174-Remove Nth Node From End of List-Easy
174. Remove Nth Node From End of List Given a linked list, remove the nth node from the end of list ...
- Mybatis日志
[DEBUG] 2018-05-20 09:56:36,404(19404) --> [main] org.slf4j.impl.JCLLoggerAdapter.trace(JCLLogger ...
- git pull 撤销误操作
本来想把github上的release合并到本地的release分支上,由于没有查看当前分支,直接运用git pull origin v2.8.1,结果将release合并到了v2.8.1分支中. 解 ...
- c#泛型约束 (where T:class)
.NET支持的类型参数约束有以下五种:where T : struct | T必须是一个结构类型where T : class ...
- visual studio常用技法相关
(1)查看dll里面包含了那些函数(dumpbin是visual studio内置工具)dumpbin -exports user32.lib (2)#include "stdlib.h&q ...
- 从零开始,搭建 AI 音箱 Alexa 语音服务
https://blog.csdn.net/gitchat/article/details/78869367
- Active Record Query Interface 数据查询接口(界面) 看到第8节。
http://guides.rubyonrails.org/active_record_querying.html ✅How to find records using a variety of me ...
- vue引用ionic4
现在的Ionic4已经开始支持VUE和REACT了.个人之前开发用IONIC.现在用VUE开发还是想用IONIC.刚好 也是支持VUE了. 在vue的项目里安装ionic依赖 npm install ...