Data Structure and Algorithm - Day 13 - Course End
- 
LRU Cache (least recently used)
multi-level cache in CPU
LRU: Hash Table + Double Linked List
Time complexity: O(1) lookup, O(1) update/modify
 - 
146. LRU Cache
Design a data structure that follows the constraints of a Least Recently Used (LRU) cache.
Implement the
LRUCacheclass:LRUCache(int capacity)Initialize the LRU cache with positive sizecapacity.int get(int key)Return the value of thekeyif the key exists, otherwise return-1.void put(int key, int value)Update the value of thekeyif thekeyexists. Otherwise, add thekey-valuepair to the cache. If the number of keys exceeds thecapacityfrom this operation, evict the least recently used key.
Follow up:
Could you dogetandputinO(1)time complexity?Example 1:
Input ["LRUCache", "put", "put", "get", "put", "get", "put", "get", "get", "get"] [[2], [1, 1], [2, 2], [1], [3, 3], [2], [4, 4], [1], [3], [4]] Output [null, null, null, 1, null, -1, null, -1, 3, 4] Explanation LRUCache lRUCache = new LRUCache(2); lRUCache.put(1, 1); // cache is {1=1} lRUCache.put(2, 2); // cache is {1=1, 2=2} lRUCache.get(1); // return 1 lRUCache.put(3, 3); // LRU key was 2, evicts key 2, cache is {1=1, 3=3} lRUCache.get(2); // returns -1 (not found) lRUCache.put(4, 4); // LRU key was 1, evicts key 1, cache is {4=4, 3=3} lRUCache.get(1); // return -1 (not found) lRUCache.get(3); // return 3 lRUCache.get(4); // return 4Constraints:
1 <= capacity <= 30000 <= key <= 30000 <= value <= 104- At most 
3 * 104calls will be made togetandput. 
class LRUCache { class DLinkedNode { int key; int value; DLinkedNode pre; DLinkedNode next; public DLinkedNode () { } public DLinkedNode (int key, int value) { this.key = key; this.value = value; } } private Map<Integer, DLinkedNode> cache = new HashMap<>(); private int size; private int cap; private DLinkedNode head, tail; public LRUCache(int capacity) { this.size = 0; this.cap = capacity; head = new DLinkedNode(); tail = new DLinkedNode(); head.next = tail; tail.pre = head; } public int get(int key) { DLinkedNode node = cache.get(key); if (node == null) { return -1; } moveToHead(node); return node.value; } public void put(int key, int value) { DLinkedNode node = cache.get(key); if (node == null) { DLinkedNode newNode = new DLinkedNode(key, value); cache.put(key, newNode); addToHead(newNode); size++; if (size > cap) { DLinkedNode tail = removeTail(); cache.remove(tail.key); size--; } } else { node.value = value; moveToHead(node); } } private void moveToHead(DLinkedNode node) { removeNode(node); addToHead(node); } private void removeNode(DLinkedNode node) { node.pre.next = node.next; node.next.pre = node.pre; } private void addToHead(DLinkedNode node) { node.pre = head; node.next = head.next; head.next.pre = node; head.next = node; } private DLinkedNode removeTail() { DLinkedNode res = tail.pre; removeNode(res); return res; } } - 
Bloom Filter
套在外层的缓存!
一个很长的二进制向量和一系列随机映射函数。
布隆过滤器可以用于检索一个元素是否在一个集合中。
优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
只要有一个映射位是0,元素一定不存在;映射位都是1也不一定存在,存在误差。
案例:
- 比特币网络
 - 分布式系统(Map-Reduce) - Hadoop、search engine
 - Redis缓存
 - 垃圾邮件、评论等的过滤
 
 - 
Sort
重点:堆排序,快速排序,归并排序
归并:先排序左右子数组,然后合并两个有序子数组
快排:先调配出左右子数组,然后对于左右子数组进行排序 - 
1122. Relative Sort Array
Given two arrays
arr1andarr2, the elements ofarr2are distinct, and all elements inarr2are also inarr1.Sort the elements of
arr1such that the relative ordering of items inarr1are the same as inarr2. Elements that don't appear inarr2should be placed at the end ofarr1in ascending order.Example 1:
Input: arr1 = [2,3,1,3,2,4,6,7,9,2,19], arr2 = [2,1,4,3,9,6] Output: [2,2,2,1,4,3,3,9,6,7,19]Constraints:
1 <= arr1.length, arr2.length <= 10000 <= arr1[i], arr2[i] <= 1000- All the elements of 
arr2are distinct. - Each 
arr2[i]is inarr1. 
class Solution { public int[] relativeSortArray(int[] arr1, int[] arr2) { int i = 0; for (int i2 = 0; i2 < arr2.length; i2++) { for (int i1 = 0; i1 < arr1.length; i1++) { if (arr1[i1] == arr2[i2]) { int t = arr1[i]; arr1[i++] = arr1[i1]; arr1[i1] = t; } } } Arrays.sort(arr1, i, arr1.length); return arr1; } } - 
56. Merge Intervals
Given an array of
intervalswhereintervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.Example 1:
Input: intervals = [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].Example 2:
Input: intervals = [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considered overlapping.Constraints:
1 <= intervals.length <= 104intervals[i].length == 20 <= starti <= endi <= 104
class Solution { public int[][] merge(int[][] intervals) { Deque<int[]> deque = new LinkedList<>(); Arrays.sort(intervals, (x,y)->(x[1]-y[1])); Arrays.sort(intervals, (x,y)->(x[0]-y[0])); for (int[] interval : intervals) { if (deque.isEmpty()) { deque.addLast(interval); continue; } int end = deque.peekLast()[1]; if (interval[0] <= end) { deque.peekLast()[1] = Math.max(end, interval[1]); } else { deque.addLast(interval); } } int n = deque.size(); int[][] res = new int[n][2]; for (int i = 0; i < n; i++) { res[i] = deque.pollFirst(); } return res; } } - 
493. Reverse Pairs
Given an array
nums, we call(i, j)an *important reverse pair* ifi < jandnums[i] > 2*nums[j].You need to return the number of important reverse pairs in the given array.
Example1:
Input: [1,3,2,3,1] Output: 2Example2:
Input: [2,4,3,5,1] Output: 3Note:
- The length of the given array will not exceed 
50,000. - All the numbers in the input array are in the range of 32-bit integer.
 
class Solution { int res = 0; public int reversePairs(int[] nums) { mergeSort(nums, 0, nums.length - 1); return res; } private void mergeSort(int[] nums, int left, int right) { if (right <= left) return ; int mid = (right - left) / 2 + left; mergeSort(nums, left, mid); mergeSort(nums, mid + 1, right); merge(nums, left, mid, right); } private void merge(int[] nums, int l1, int r1, int r2) { // count res int p = l1, q = r1 + 1; while (p <= r1 && q <= r2) { if (nums[p] > (long) nums[q] * 2) { res += r1 - p + 1; q++; } else p++; } int[] arr = new int[r2 - l1 + 1]; int start = l1, i = 0, l2 = r1 + 1; while (l1 <= r1 && l2 <= r2) { arr[i++] = nums[l1] > nums[l2] ? nums[l2++] : nums[l1++]; } while (l1 <= r1) arr[i++] = nums[l1++]; while (l2 <= r2) arr[i++] = nums[l2++]; for (l1 = start; l1 <= r2; l1++) { nums[l1] = arr[l1 - start]; } } } - The length of the given array will not exceed 
 
                    
                
                
            
        
浙公网安备 33010602011771号