思路一(哈希表 + 双向链表):
1、通过题目分析,put操作:如果key不在缓存中那我们需要进行结点的插入操作,若插入时缓存已满则先删除最久未访问的结点再插入。这里我们可以想到双向链表,头部存储近来访问结点,尾部存储最久未访问结点。get操作,若存在key则返回结点的value,这里get相称于一个查找,所以我们可以想到哈希表,如许我们就能快速的进行结点的查找和定位。
2、具体思路如下:
① 我们创建一个头结点和一个额外的尾结点来方便结点的插入和删除操作。
② 插入操作(put):我们将刚插入的元素或者近来使用的元素放在链表的头部,则尾部为最长时间未使用的元素。
若要插入结点key时,之前存在序号为key的结点则移到链表头部。
若要插入节点key时,之前不存在序号为key的结点,且结点数未满则插入链表头部,若结点数已满则插入后删除尾结点。
③ 获取操作(get):分析到获取我们很快能想到哈希表,因哈希表能让我们快速的进行查找操作,所以上述插入和删除时需要维护一个哈希表。
若结点不在哈希表中则返回-1。
若存在哈希表中则返回值,并将结点移动到头部。
力扣官方题解链接(有缓存 get() 和put () 过程图很不错)
3、复杂度分析
① 时间复杂度:对于 put 和 get 都是 O(1)。
② 空间复杂度:O(capacity),因为哈希表和双向链表最多存储 capacity+1 个元素。
代码实现(思路一(哈希表 + 双向链表)):