返回股票價格變化程度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:
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的股票