力扣刷题之有序集合
一、TreeMap
TreeMap按照key進行排序
TreeMap底層是根據紅黑樹的數據結構構建的,默認是根據key的自然排序來組織(比如integer的大小,String的字典排序)
TreeMap<Integer,Integer> map1 = new TreeMap<Integer,Integer>(); //默認的TreeMap升序排列 TreeMap<Integer,Integer> map2= new TreeMap<Integer,Integer>(new Comparator<Integer>(){/* * int compare(Object o1, Object o2) 返回一個基本類型的整型, * 返回負數表示:o1 小于o2, * 返回0 表示:o1和o2相等, * 返回正數表示:o1大于o2。 */ public int compare(Integer a,Integer b){return b-a; }});2. TreeMap按照value進行排序
TreeMap只能根據key來排序,是不能根據value來排序的(否則key來排序根本就不能形成TreeMap)。如果要根據treeMap中的value排序。所以網上看了一下,大致的思路是把TreeMap的EntrySet轉換成list,然后使用Collections.sort排序。
CompareTo方法的簡單介紹
CompareTo:方法主要可以對 Byte, Double, Integer, Float, Long 或 Short 類型的參數 進行比較:
指定的數與參數相等返回 0;
指定的數小于參數返回-1;
指定的數大于參數返回1;
實戰:股票價格的波動
力扣https://leetcode-cn.com/problems/stock-price-fluctuation/
class StockPrice {/*** 記錄時間戳到價格的映射*/private Map<Integer, Integer> map;/*** 記錄某個價格出現過幾次* 可以方便地返回最大價格和最小價格*/private TreeMap<Integer, Integer> treeMap;/*** 記錄最大的時間戳*/private int maxTimestamp;public StockPrice() {this.map = new HashMap<>();this.treeMap = new TreeMap<>();this.maxTimestamp = 0;}public void update(int timestamp, int price) {// 記錄新時間戳到價格的映射Integer oldPrice = map.put(timestamp, price);// 如果存在舊價格,則舊價格的次數減一// 如果舊價格只出現過一次,直接移除if (oldPrice != null) {int oldCount = treeMap.get(oldPrice);if (oldCount == 1) {treeMap.remove(oldPrice);} else {treeMap.put(oldPrice, oldCount - 1);}}// 更新新價格的次數treeMap.put(price, treeMap.getOrDefault(price, 0) + 1);// 記錄最大時間戳if (timestamp > maxTimestamp) {maxTimestamp = timestamp;}}public int current() {return map.get(maxTimestamp);}public int maximum() {return treeMap.lastKey();}public int minimum() {return treeMap.firstKey();} }二、大頂堆、小頂堆
java使用PriorityQueue(優先隊列),一個基于優先級堆的無界優先級隊列。
實際上是一個堆(不指定Comparator時默認為最小堆),通過傳入自定義的Comparator函數可以實現大頂堆。
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>(); //小頂堆,默認容量為11 PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11,new Comparator<Integer>(){ //大頂堆,容量11@Overridepublic int compare(Integer i1,Integer i2){return i2-i1;} });PriorityQueue的常用方法有:poll(),offer(Object),size(),peek()等。
- 插入方法(offer()、poll()、remove() 、add() 方法)時間復雜度為O(log(n)) ;
- remove(Object)?和?contains(Object) 時間復雜度為O(n);
- 檢索方法(peek、element?和?size)時間復雜度為常量。
?PriorityQueue的API文檔說明:
| PriorityQueue() ??????????使用默認的初始容量(11)創建一個?PriorityQueue,并根據其自然順序對元素進行排序。 |
| PriorityQueue(Collection<? extends?E>?c) ??????????創建包含指定 collection 中元素的?PriorityQueue。 |
| PriorityQueue(int?initialCapacity) ??????????使用指定的初始容量創建一個?PriorityQueue,并根據其自然順序對元素進行排序。 |
| PriorityQueue(int?initialCapacity,?Comparator<? super?E>?comparator) ??????????使用指定的初始容量創建一個?PriorityQueue,并根據指定的比較器對元素進行排序。 |
| PriorityQueue(PriorityQueue<? extends?E>?c) ??????????創建包含指定優先級隊列元素的?PriorityQueue。 |
| PriorityQueue(SortedSet<? extends?E>?c) ??????????創建包含指定有序 set 元素的?PriorityQueue。 |
?
| ?boolean | add(E?e) ??????????將指定的元素插入此優先級隊列。 | |
| ?void | clear() ??????????從此優先級隊列中移除所有元素。 | |
| ?Comparator<? super?E> | comparator() ??????????返回用來對此隊列中的元素進行排序的比較器;如果此隊列根據其元素的自然順序進行排序,則返回?null。 | |
| ?boolean | contains(Object?o) ??????????如果此隊列包含指定的元素,則返回?true。 | |
| ?Iterator<E> | iterator() ??????????返回在此隊列中的元素上進行迭代的迭代器。 | |
| ?boolean | offer(E?e) ??????????將指定的元素插入此優先級隊列。 | |
| ?E | peek() ??????????獲取但不移除此隊列的頭;如果此隊列為空,則返回?null。 | |
| ?E | poll() ??????????獲取并移除此隊列的頭,如果此隊列為空,則返回?null。 | |
| ?boolean | remove(Object?o) ??????????從此隊列中移除指定元素的單個實例(如果存在)。 | |
| ?int | size() ??????????返回此 collection 中的元素數。 | |
| ?Object[] | toArray() ??????????返回一個包含此隊列所有元素的數組。 | |
| toArray(T[]?a) ??????????返回一個包含此隊列所有元素的數組;返回數組的運行時類型是指定數組的類型。 |
| addAll,?element,?remove |
| containsAll,?isEmpty,?removeAll,?retainAll,?toString |
| clone,?equals,?finalize,?getClass,?hashCode,?notify,?notifyAll,?wait,?wait,?wait |
| containsAll,?equals,?hashCode,?isEmpty,?removeAll,?retainAll |
還是上面那道題
class StockPrice {/*** 記錄時間到價格的映射*/private Map<Integer, Price> map;/*** 小頂堆,最小的價格在堆頂*/private PriorityQueue<Price> minHeap;/*** 大頂堆,最大的價格在堆頂*/private PriorityQueue<Price> maxHeap;/*** 記錄最大的時間戳*/private int maxTimestamp;public StockPrice() {this.map = new HashMap<>();this.minHeap = new PriorityQueue<>((p1, p2) -> p1.price - p2.price);this.maxHeap = new PriorityQueue<>((p1, p2) -> p2.price - p1.price);this.maxTimestamp = 0;}public void update(int timestamp, int price) {// 新的價格Price p = new Price(price);// 判斷舊的價格是否存在,存在的話把它更新成是錯誤的價格Price oldP = map.put(timestamp, p);if (oldP != null) {oldP.error = true;}// 添加到小頂堆和大頂堆minHeap.offer(p);maxHeap.offer(p);// 記錄最大時間戳if (timestamp > maxTimestamp) {maxTimestamp = timestamp;}}public int current() {// 返回最大時間戳處的價格return map.get(maxTimestamp).price;}public int maximum() {// 把堆頂非最新的價格移除while (!maxHeap.isEmpty() && maxHeap.peek().error) {maxHeap.poll();}// 返回堆頂最大的價格return maxHeap.peek().price;}public int minimum() {// 把堆頂非最新的價格移除while (!minHeap.isEmpty() && minHeap.peek().error) {minHeap.poll();}// 返回堆頂最小的價格return minHeap.peek().price;}/*** 定義一個價格類,這個類記錄著這個價格是不是錯誤的*/private static class Price {boolean error;int price;Price(int price) {this.price = price;this.error = false;}} }總結
- 上一篇: 常见正则表达式
- 下一篇: Tomcat线程连接池参数优化