返回股票价格变化程度top k的股票

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了返回股票价格变化程度top k的股票相关的知识,希望对你有一定的参考价值。

第二题:有一个数据流
持续的读入以下数据:stock,price
每天早上都是从empty开始读入数据
设计一个application,能始终返回股票价格变化程度top k的股票

我用的hashmap加priorityqueue做的,每次有新数据的时候,检查hashmap里面有没有,如果没有的话,插入到hashmap和priorityqueue。如果有的话,删除priorityqueue里面的东西,然后更新price diff再插入,每次top k的request都是pop出k的然后再插回去。
这轮我不知道maxheap还有一个findnext的功能(这是面试官说的,虽然我当时感觉maxheap应该不可能实现constant time findnext功能的,并且给他解释了为什么,但是他还是说有这样一个method,但是我doubt他知道这个method的内部实现。当然我也没有继续坚持,只是说谢谢你让我知道了一个新method。后来我查了java的priorityqueue的methods里并没有这样一个iterator,希望有知道的同学可以讨论一下),所以每次request的时候都是先pop出来再插进去导致了klgn的复杂度,最后面试官说有这样一个method能够constant time返回下一个大的node, 这样top k request的时候就是O(k)的复杂度。

 

注意1:该队列是用数组实现,但是数组大小可以动态增加,容量无限。
注意2:此实现不是同步的。不是线程安全的。如果多个线程中的任意线程从结构上修改了列表, 则这些线程不应同时访问 PriorityQueue 实例,这时请使用线程安全的PriorityBlockingQueue 类。
注意3:不允许使用 null 元素。
注意4:此实现为插入方法(offer、poll、remove() 和 add 方法)提供 O(log(n)) 时间;
为 remove(Object) 和 contains(Object) 方法提供线性时间;
为检索方法(peek、element 和 size)提供固定时间。
注意5:方法iterator()中提供的迭代器并不保证以有序的方式遍历优先级队列中的元素。
 
所以每次插入树O(n) 时间复杂度。
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;

class Solution {
    private class Node {
        String name;
        double diff;
        double pri;

        public Node(String name, double diff, double pri) {
            this.name = name;
            this.diff = diff;
            this.pri = pri;
        }
    }
    HashMap<String, Node> map = new HashMap<>();
    Comparator<Node> com = new Comparator<Node>() {
        @Override
        public int compare(Node o1, Node o2) {
            return (int)(o1.diff - o2.diff);
        }
    };
    PriorityQueue<Node> pq = new PriorityQueue<>(com);

    public void topK(String[][] prices, int k) {

        for (String[] cur : prices) {
            if (!map.containsKey(cur[0])) {
                map.put(cur[0], new Node(cur[0], 0.0, Double.valueOf(cur[1])));
            } else {
                Node pre = map.get(cur[0]);
                double dif = Math.abs(pre.pri - Double.valueOf(cur[1]));
                if (pq.contains(pre)) {
                    pq.remove(pre);
                }
                Node newNode = new Node(cur[0], dif, Double.valueOf(cur[1]));
                map.put(cur[0], newNode);
                pq.add(newNode);
                while (pq.size() > k) {
                    pq.poll();
                }
            }
        }
        for (Node no : pq) {
            System.out.println(no.name + no.pri);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Solution sol = new Solution();
        //String[][] nums = new String[][]{{"aa", "1.1"}, {"aa", "2.5"}, {"b", "1"}, {"aa", "2.9"}};
        //int[][] lands = new int[][]{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}};
        //String s = "abcacd";
        //System.out.println(sol.sort(lands));

        String[][] nums = new String[][]{{"b", "1.1"}, {"aa", "2.5"}, {"b", "1"}, {"aa", "2.9"}};
        sol.topK(nums, 2);
    }
TreeMap 或者 TreeSet 删除又可以 o(lgn), 插入也是O(lgn)。 这样就快了。 under the hood, 其实就是一个BST.
hashmap用以快速更新 node 的max, min value,  然后treeset 就可以自动lgn调整 key (diff) 的顺序了。
import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeSet;

class Solution {
    private class Node {
        String name;
        double diff;
        double pri;

        public Node(String name, double diff, double pri) {
            this.name = name;
            this.diff = diff;
            this.pri = pri;
        }
    }
    HashMap<String, Node> map = new HashMap<>();
    Comparator<Node> com = new Comparator<Node>() {
        @Override
        public int compare(Node o1, Node o2) {
            return (int)(o1.diff - o2.diff);
        }
    };
    TreeSet<Node> pq = new TreeSet<>(com);

    public void topK(String[][] prices, int k) {

        for (String[] cur : prices) {
            if (!map.containsKey(cur[0])) {
                map.put(cur[0], new Node(cur[0], 0.0, Double.valueOf(cur[1])));
            } else {
                Node pre = map.get(cur[0]);
                double dif = Math.abs(pre.pri - Double.valueOf(cur[1]));
                if (pq.contains(pre)) {
                    pq.remove(pre);
                }
                Node newNode = new Node(cur[0], dif, Double.valueOf(cur[1]));
                map.put(cur[0], newNode);
                pq.add(newNode);

                System.out.println(pq.size());
                System.out.println(pq.first().name + pq.first().pri + " " + pq.last().name + " " + pq.last().pri);
                while (pq.size() > k) {
                    pq.pollFirst();
                }
            }
        }
        for (Node no : pq) {
            System.out.println(no.name + no.pri);
        }
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Solution sol = new Solution();
        String[][] nums = new String[][]{{"aa", "1.1"},  {"bb", "1"}, {"bb", "1.8"},{"aa", "2.5"}, {"aa", "2.51"}};
        sol.topK(nums, 2);
    }
}

第二轮:. more info on 
第一题:leetcode 232
第二题:一个matrix里,有一些element有treasure,从左上角走到右下角,只能往下往右,求最大能得到的treasure的值,标准二维dp解的
第三题:leetcode 138, 我说我做过了,他就换了一道
第四题:leetcode 98

 

以上是关于返回股票价格变化程度top k的股票的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点# 面试必刷TOP101:买卖股票的最好时机

iOS上股票类应用中的K线图效果怎么实现

股票K线里面的obv啥意思?

901. 股票价格跨度(递减栈)

股票投资相关,成交量怎么看

价格与指标