[英]Stock ticker data structure for getting top k stock prices
我正在練習一些面試問題,而遇到的一個問題是股票行情記錄器數據結構問題。
給定一連串的股價,編寫一個支持以下操作的數據結構:
1. StockSticker(int k) : Initialize the size of the ticker.
2. void addOrUpdate(String stock, double price) : Add or update a stock.
3. List<Stock> top(int k) : Get top k stocks.
我的想法是將HashMap與快速選擇算法結合使用,以獲得top(k)函數的平均情況O(n)復雜度。 在處理價值流時,這將是一個有效的解決方案,還是有更好的選擇? 我唯一的其他想法是使用堆,但是我不確定如何以使其優於O(n)的方式進行操作。
這是我的解決方案:
public class StockTicker {
public class Stock{
String sym;
double price;
public Stock(String s, double val){
this.sym = s;
this.price = val;
}
}
HashMap<String,Stock> st;
HashMap<String,Integer> ind;
int unique;
int max;
Stock[] stocks;
public StockTicker(int k){
this.unique = 0;
this.max = k;
this.st = new HashMap<String, Stock>();
this.ind = new HashMap<String, Integer>();
this.stocks = new Stock[k];
}
public void addOrUpdate(String sym, double price){
if(!st.containsKey(sym)){
Stock stock = new Stock(sym,price);
st.put(sym, stock);
ind.put(sym, unique);
stocks[unique++] = stock;
}
else{
Stock update = st.get(sym);
update.price = price;
}
}
public List<Stock> top(int k){
List<Stock> res = new ArrayList<Stock>();
Stock[] temp = new Stock[max];
for(int i = 0; i < temp.length; i++){
temp[i] = new Stock(stocks[i].sym, stocks[i].price);
}
int top = quickselect(temp, 0, temp.length-1, k);
for(int i = 0; i <= top; i++){
res.add(temp[i]);
}
return res;
}
public int quickselect(Stock[] stocks, int left, int right, int kth){
if(left == right){
return left;
}
int split = partition(stocks, left,right);
if(kth-1 == split){ return split;}
else if(kth-1 > split){ return quickselect(stocks,split + 1, right, kth);}
else { return quickselect(stocks, left , split-1, kth);}
}
public int partition(Stock[] stocks, int left, int right){
int lastIndex = right;
double pivot = stocks[lastIndex].price;
while(left <= right){
while( left <= right && stocks[left].price > pivot ){
left++;
}
while( left <= right && stocks[right].price <= pivot){
right--;
}
if(left <= right && stocks[left].price <= pivot && stocks[right].price > pivot){
swap(stocks,left,right);
}
}
swap(stocks,left,lastIndex);
return left;
}
public void swap(Stock[] stocks, int x, int y){
Stock eleX = stocks[x];
Stock eleY = stocks[y];
stocks[x] = eleY;
stocks[y] = eleX;
}
public Stock getStock(String sym){
return st.get(sym);
}
public static void main(String[] args){
StockTicker ticker = new StockTicker(10);
ticker.addOrUpdate("A", 10.00);
ticker.addOrUpdate("B", 1.00);
ticker.addOrUpdate("C", 9.00);
ticker.addOrUpdate("D", 2.00);
ticker.addOrUpdate("E", 8.00);
ticker.addOrUpdate("F", 3.00);
ticker.addOrUpdate("G", 7.00);
ticker.addOrUpdate("H", 4.00);
ticker.addOrUpdate("I", 6.00);
ticker.addOrUpdate("J", 5.00);
List<Stock> topStocks = ticker.top(5);
for(Stock s: topStocks){
System.out.print(s.sym + ": " + s.price + " ");
}
}
}
對於較小的k
您可以做得更好:您可以維護優先級隊列,最多彈出k
次,然后將這些元素添加回隊列,以在O(k log n)
時間內回答前k
查詢。
事實上,你可以回答每個查詢O(k + log N)
為任意值時k
,但它需要實現自定義的平衡二叉搜索樹(與自定義的樹,你只需要通過拆分它k
-職位),但實施起來可能非常繁瑣。
我認為這是一個經典的“優先隊列”用例,您只需要在出現新價格時處理邏輯,就需要更改已在隊列中的股票價格。
這是官方文檔中的python解決方案: https : //docs.python.org/2/library/heapq.html#priority-queue-implementation-notes
或正是您所需要的索引優先級隊列的Java實現: https : //algs4.cs.princeton.edu/24pq/IndexMinPQ.java.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.