【问题标题】:Stock ticker data structure for getting top k stock prices用于获取前 k 个股票价格的股票代码数据结构
【发布时间】:2017-04-21 19:47:27
【问题描述】:

我正在练习一些面试问题,其中一个是股票代码数据结构问题。

给定一个股票价格流,编写一个支持以下操作的数据结构:

 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 个元素吗?
  • 价格最高的股票。快速选择对数组进行分区,以便 k 左侧的每个元素都有更大或相等的价格。
  • 另外,问题没有说明股票是否需要按任何特定顺序排列,但这将是一个很好的跟进。

标签: java algorithm data-structures


【解决方案1】:

对于小的k,您可以做得更好:您可以维护一个优先级队列,弹出最大的k 次并将这些元素添加回队列以在O(k log n) 时间回答顶部的k 查询。

事实上,对于k 的任何值,您都可以在O(k + log N) 时间内回答每个查询,但它需要实现自定义平衡二叉搜索树(使用自定义树,您只需将其用@ 拆分) 987654327@-th 位置),但实施起来可能非常乏味。

【讨论】:

    【解决方案2】:

    我认为这是一个经典的优先队列用例,您只需要处理新价格到来时的逻辑,并且您需要更改已经在队列中的股票的价格。

    这是来自官方文档的 python 解决方案: https://docs.python.org/2/library/heapq.html#priority-queue-implementation-notes

    或者是您所需要的索引优先级队列的 Java 实现: https://algs4.cs.princeton.edu/24pq/IndexMinPQ.java.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-04
      • 2021-03-05
      • 2011-03-15
      • 2011-03-23
      • 1970-01-01
      • 2014-10-16
      • 1970-01-01
      相关资源
      最近更新 更多