LRU是什么?
首先考虑这样的一个业务场景,小王在A公司上班,有一天产品提出了一个需求:“咱们系统的用户啊,每天活跃的就那么多,有太多的僵尸用户,根本不登录,你能不能考虑做一个筛选机制把这些用户刨出去,并且给活跃的用户做一个排名,我们可以设计出一些奖励活动,提升咱们的用户粘性,咱们只需要关注那些活跃的用户就行了“”。小王连忙点头,说可以啊,然而心里犯起嘀咕来了:这简单,按照常规思路,给用户添加一个最近活跃时间长度和登录次数,然后按照这两个数据计算他们的活跃度,最后直接排序就行了。嘿嘿,简直完美!不过!用户表字段已经很多了,又要加两个字段,然后还得遍历所有的数据排序?这样查询效率是不是会受影响啊?并且公司的服务器上次就蹦过一次,差点没忙出命来才调好。有没有更优雅的一种方式呢?小王面朝天空45°,陷入了无限的思考中…
按照英文的直接原义就是Least Recently Used, 最近最少使用,它是按照一个非常著名的计算机操作系统基础理论得来的:最近使用的页面数据会在未来一段时期内仍然被使用,已经很久没有使用的页面很有可能在未来较长的一段时间内仍然不会被使用。基于这个思想,会存在一种缓存淘汰机制,每次从内存中找到最久未使用的数据然后置换出来,从而存入新的数据!它的主要衡量指标是使用的时间,附加指标是使用的次数。在计算机中大量使用了这个机制,它的合理性在于优先筛选热点数据,所谓热点数据,就是最近最多使用的数据!因为,利用LRU我们可以解决很多实际开发中的问题,并且很符合业务场景。
当小王看到LRU的时候,瞬间感觉抓住了救命稻草,这个算法不是就完全契合产品的需求吗?只要把用户数据按照LRU去筛选,利用数据结构完成的事情,完全减少了自己存储、添加字段判断、排序的过程,这样对于提高服务器性能肯定有很大的帮助,岂不美哉!小王考虑好之后,就决定先写一个demo来实现LRU,那么在java中是如何实现LRU呢?考虑了许久,小王写下了这些代码。
HashMap和LinkedList实现LRU
题目描述:题目描述
设计LRU缓存结构,该结构在构造时确定大小,假设大小为K,并有如下两个功能
set(key, value):将记录(key, value)插入该结构
get(key):返回key对应的value值
[要求]
set和get方法的时间复杂度为O(1)
某个key的set或get操作一旦发生,认为这个key的记录成了最常使用的。
当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的。
若opt=1,接下来两个整数x, y,表示set(x, y)
若opt=2,接下来一个整数x,表示get(x),若x未出现过或已被移除,则返回-1
对于每个操作2,输出一个答案
输入:
[[1,1,1],[1,2,2],[1,3,2],[2,1],[1,4,4],[2,2]],3
输出:
[1,-1]
代码实现:
import java.util.*;public class Solution {private int capacity;private HashMap<Integer, Integer> map;private List<Integer> list;/*** lru design* @param operators int整型二维数组 the ops* @param k int整型 the k* @return int整型一维数组*/public int[] LRU (int[][] operators, int k) {capacity = k;map = new HashMap<>(k);list = new LinkedList<>();List<Integer> output = new ArrayList<>();int temp;// write code herefor(int i = 0, j = operators.length;i < j;i ++){if(operators[i][0] == 1){set(operators[i][1], operators[i][2]);}else {output.add(get(operators[i][1]));}}int [] out = new int[output.size()];for(int i = 0;i < out.length;i ++){out[i] = output.get(i);}return out;}public void set(int key, int value){if(map.containsKey(key)){list.remove(key);list.add(0, key);}else {if(map.size() == capacity){map.remove(list.remove(capacity - 1));}list.add(0, key);map.put(key, value);}}public int get(int key){if(map.get(key) != null){list.remove(new Integer(key));list.add(0, key);return map.get(key);}return -1;}}
/wyq178/p/9976815.html
如果觉得《面试:算法LRU(Least Recently Used) 字节跳动Java研发算法题》对你有帮助,请点赞、收藏,并留下你的观点哦!