博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Leetcode: LFU Cache && Summary of various Sets: HashSet, TreeSet, LinkedHashSet
阅读量:6978 次
发布时间:2019-06-27

本文共 8024 字,大约阅读时间需要 26 分钟。

Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and set.get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.set(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted.Follow up:Could you do both operations in O(1) time complexity?Example:LFUCache cache = new LFUCache( 2 /* capacity */ );cache.set(1, 1);cache.set(2, 2);cache.get(1);       // returns 1cache.set(3, 3);    // evicts key 2cache.get(2);       // returns -1 (not found)cache.get(3);       // returns 3.cache.set(4, 4);    // evicts key 1.cache.get(1);       // returns -1 (not found)cache.get(3);       // returns 3cache.get(4);       // returns 4

referred to: https://discuss.leetcode.com/topic/69137/java-o-1-accept-solution-using-hashmap-doublelinkedlist-and-linkedhashset

Two HashMaps are used, one to store <key, value> pair, another store the <key, node>.

I use double linked list to keep the frequent of each key. In each double linked list node, keys with the same count are saved using java built in LinkedHashSet. This can keep the order.
Every time, one key is referenced, first find the current node corresponding to the key, If the following node exist and the frequent is larger by one, add key to the keys of the following node, else create a new node and add it following the current node.
All operations are guaranteed to be O(1).

1 public class LFUCache {  2     int cap;  3     ListNode head;  4     HashMap
valueMap; 5 HashMap
nodeMap; 6 7 public LFUCache(int capacity) { 8 this.cap = capacity; 9 this.head = null; 10 this.valueMap = new HashMap
(); 11 this.nodeMap = new HashMap
(); 12 } 13 14 public int get(int key) { 15 if (valueMap.containsKey(key)) { 16 increaseCount(key); 17 return valueMap.get(key); 18 } 19 return -1; 20 } 21 22 public void set(int key, int value) { 23 if (cap == 0) return; 24 if (valueMap.containsKey(key)) { 25 valueMap.put(key, value); 26 increaseCount(key); 27 } 28 else { 29 if (valueMap.size() < cap) { 30 valueMap.put(key, value); 31 addToHead(key); 32 } 33 else { 34 removeOld(); 35 valueMap.put(key, value); 36 addToHead(key); 37 } 38 } 39 40 } 41 42 public void increaseCount(int key) { 43 ListNode node = nodeMap.get(key); 44 node.keys.remove(key); 45 if (node.next == null) { 46 node.next = new ListNode(node.count+1); 47 node.next.prev = node; 48 node.next.keys.add(key); 49 } 50 else if (node.next.count == node.count + 1) { 51 node.next.keys.add(key); 52 } 53 else { 54 ListNode newNode = new ListNode(node.count+1); 55 newNode.next = node.next; 56 node.next.prev = newNode; 57 newNode.prev = node; 58 node.next = newNode; 59 node.next.keys.add(key); 60 } 61 nodeMap.put(key, node.next); 62 if (node.keys.size() == 0) remove(node); 63 } 64 65 public void remove(ListNode node) { 66 if (node.next != null) { 67 node.next.prev = node.prev; 68 } 69 if (node.prev != null) { 70 node.prev.next = node.next; 71 } 72 else { // node is head 73 head = head.next; 74 } 75 } 76 77 public void addToHead(int key) { 78 if (head == null) { 79 head = new ListNode(1); 80 head.keys.add(key); 81 } 82 else if (head.count == 1) { 83 head.keys.add(key); 84 } 85 else { 86 ListNode newHead = new ListNode(1); 87 head.prev = newHead; 88 newHead.next = head; 89 head = newHead; 90 head.keys.add(key); 91 } 92 nodeMap.put(key, head); 93 } 94 95 public void removeOld() { 96 if (head == null) return; 97 int old = 0; 98 for (int keyInorder : head.keys) { 99 old = keyInorder;100 break;101 }102 head.keys.remove(old);103 if (head.keys.size() == 0) remove(head);104 valueMap.remove(old);105 nodeMap.remove(old);106 }107 108 public class ListNode {109 int count;110 ListNode prev, next;111 LinkedHashSet
keys;112 public ListNode(int freq) {113 count = freq;114 keys = new LinkedHashSet
();115 prev = next = null;116 }117 }118 }119 120 /**121 * Your LFUCache object will be instantiated and called as such:122 * LFUCache obj = new LFUCache(capacity);123 * int param_1 = obj.get(key);124 * obj.set(key,value);125 */

 

 

Summary of LinkedHashSet: 

A Set contains no duplicate elements. That is one of the major reasons to use a set. There are 3 commonly used implementations of Set: HashSet, TreeSet and LinkedHashSet. When and which to use is an important question. In brief, if you need a fast set, you should use HashSet; if you need a sorted set, then TreeSet should be used; if you need a set that can be store the insertion order, LinkedHashSet should be used.

1. Set Interface

Set interface extends Collection interface. In a set, no duplicates are allowed. Every element in a set must be unique. You can simply add elements to a set, and duplicates will be removed automatically.

2. HashSet vs. TreeSet vs. LinkedHashSet

HashSet is Implemented using a hash table. Elements are not ordered. The add, remove, and contains methods have constant time complexity O(1).

TreeSet is implemented using a tree structure(red-black tree in algorithm book). The elements in a set are sorted, but the add, remove, and contains methods has time complexity of O(log (n)). It offers several methods to deal with the ordered set like first(), last(), headSet(), tailSet(), etc.

LinkedHashSet is between HashSet and TreeSet. It is implemented as a hash table with a linked list running through it, so it provides the order of insertion. The time complexity of basic methods is O(1).

3. TreeSet Example

TreeSet
tree = new TreeSet
();tree.add(12);tree.add(63);tree.add(34);tree.add(45); Iterator
iterator = tree.iterator();System.out.print("Tree set data: ");while (iterator.hasNext()) { System.out.print(iterator.next() + " ");}

Output is sorted as follows:

Tree set data: 12 34 45 63

4. HashSet Example

HashSet
dset = new HashSet
();dset.add(new Dog(2));dset.add(new Dog(1));dset.add(new Dog(3));dset.add(new Dog(5));dset.add(new Dog(4));Iterator
iterator = dset.iterator();while (iterator.hasNext()) { System.out.print(iterator.next() + " ");}

Output:

5 3 2 1 4

Note the order is not certain.

5. LinkedHashSet Example

LinkedHashSet
dset = new LinkedHashSet
();dset.add(new Dog(2));dset.add(new Dog(1));dset.add(new Dog(3));dset.add(new Dog(5));dset.add(new Dog(4));Iterator
iterator = dset.iterator();while (iterator.hasNext()) { System.out.print(iterator.next() + " ");}

The order of the output is certain and it is the insertion order:

2 1 3 5 4

转载地址:http://weupl.baihongyu.com/

你可能感兴趣的文章
Flex通信-Java服务端通信实例
查看>>
Nginx学习笔记(一) Nginx架构
查看>>
JavaScript sync and async(同步和异步)
查看>>
.Net Winform 开发笔记(四) 透过现象看本质
查看>>
Linux下显示硬盘空间的两个命令
查看>>
What’s new: Windows Phone 7 与 Windows Phone 6.5功能对比
查看>>
用Swift实现一款天气预报APP(三)
查看>>
HttpApplication事件&ASP.NET页面周期
查看>>
春天。
查看>>
MapReduce对交易日志进行排序的Demo(MR的二次排序)
查看>>
Android -- Fragment注意事项
查看>>
Android APP测试的日志文件抓取
查看>>
DevDays2012 开发者日中文版资料下载
查看>>
ios开发学习-手势交互(Gesture)效果源码分享
查看>>
推荐15个国外使用 CSS3 制作的漂亮网站
查看>>
iOS:转载:UIControl的使用
查看>>
大叔也说并行和串行`性能提升N倍(N由操作系统位数和cpu核数决定)
查看>>
对ListenSocket 的研究(四)
查看>>
JQuery:JQuery 中的CSS()方法
查看>>
Linux内核跟踪之trace框架分析【转】
查看>>