1. 程式人生 > >返回股票價格變化程度top k的股票

返回股票價格變化程度top k的股票

iter queue more ood rgs args har request blocking

第二題:有一個數據流
持續的讀入以下數據: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的股票