LRU淘汰策略实现
详情
编写代码实现LRU缓存算法,实现get put以及访问排序和最近最少使用算法的淘汰策略
思路
参考官网解答,可以使用LinkHashMap的安装访问进行排序的思路或者使用链表+map存储替换
代码
public class LruLink {
static class LruCache extends LinkedHashMap<Integer, Integer> {
private int capacity;
public LruCache(int capacity) {
super(capacity, 0.75f, true);
this.capacity = capacity;
}
public int get(int key) {
return super.getOrDefault(key, -1);
}
public void put(int key, int value) {
super.put(key, value);
}
@Override
protected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {
return size() > capacity;
}
}
/**
* 双链表+map实现lru缓存算法
*/
class LruLinkNode {
public LruLinkNode prev;
public LruLinkNode next;
int key;
int value;
public LruLinkNode() {
}
public LruLinkNode(int key, int value) {
this.key = key;
this.value = value;
}
}
private Map<Integer, LruLinkNode> map = new HashMap<>();
int capacity;
int size;
private LruLinkNode head, tail;
public LruLink(int capacity) {
this.capacity = capacity;
head = new LruLinkNode();
tail = new LruLinkNode();
tail.prev = head;
head.next = tail;
}
public int get(int key) {
LruLinkNode node = map.get(key);
if (node == null) {
return -1;
}
//被访问的数据要放到头部
moveToHead(node);
return node.value;
}
public void put(int key, int value) {
LruLinkNode node = map.get(key);
//如果Key存在 更新value 移到首部
if (node != null) {
node.value = value;
moveToHead(node);
} else {
node = new LruLinkNode(key, value);
map.put(key, node);
//添加到双向链表头部
addToHead(node);
++size;
//如果链表长度大于最大容量 移除尾部
if (size > capacity) {
map.remove(removeTail().key);
--size;
}
}
}
private LruLinkNode removeTail() {
LruLinkNode node = tail.prev;
removeNode(node);
;return node;
}
private void addToHead(LruLinkNode node) {
LruLinkNode temp = head.next;
head.next=node;
temp.prev=node;
node.next=temp;
node.prev=head;
}
private void moveToHead(LruLinkNode node) {
//移除当前节点
removeNode(node);
//添加当前节点到头部
addToHead(node);
}
public void removeNode(LruLinkNode node){
node.prev.next=node.next;
node.next.prev=node.prev;
}
public static void main(String[] args) {
// LruCache lruCache = new LruCache(4);
LruLink lruCache = new LruLink(4);
lruCache.put(1,1);
lruCache.put(2,2);
lruCache.put(3,3);
lruCache.put(4,4);
lruCache.put(5,5);
//3会被提到头部
lruCache.get(3);
//已经存在的会被踢到首部
lruCache.put(2,2);
lruCache.put(6,6);
}
}
链表翻转
详情
将给定链表头尾翻转。如1->2->3->4翻转后为 4->3->2->1
思路
使用临时节点指向,对链表遍历进行翻转
LinkNode next = cur.next;
cur.next = prev;
prev = cur;
cur = next;
代码
public static LinkList inverseLink(LinkList head) {
if (head == null || head.next == null) {
return head;
}
//定义当前节点的前一个节点 初始值设为 null
LinkList prev = null;
//定义当前节点
LinkList cur = head;
// 临时节点
LinkList temp = null;
while (cur != null) {
temp = cur.next;
cur.next = prev;
prev = cur;
cur = temp;
}
return prev;
}
public static void main(String[] args) {
LinkList head = new LinkList(0);
LinkList first = new LinkList(1);
LinkList second = new LinkList(2);
LinkList third = new LinkList(3);
LinkList fourth = new LinkList(4);
head.next = first;
first.next = second;
second.next = third;
third.next = fourth;
fourth.next = null;
LinkList linkList = inverseLink(head);
System.out.println(linkList);
}
合并K个升序链表
详情:
对k个升序的链表进行合并,合并的结果为一个升序链表
解题思路:
归并两两合并
示例:
链表1: 1->6->9->14 链表2: 3->5->8->12
合并结果: 1->3->5->6->8->9->12->14
代码:
public static LinkList mergerLinkList(LinkList[] list) {
for (int i = 1; i < list.length; i++) {
for (int j = 0; i + j < list.length; j = j + i * 2) {
list[j] = mergerTwoLinkList(list[j], list[j + i]);
}
}
return list[0];
}
private static LinkList mergerTwoLinkList(LinkList linkList1, LinkList linkList2) {
LinkList head = new LinkList();
LinkList cur = head;
while (linkList1 != null && linkList2 != null) {
if (linkList1.val < linkList2.val) {
cur.next = linkList1;
linkList1 = linkList1.next;
} else {
cur.next = linkList2;
linkList2 = linkList2.next;
}
cur = cur.next;
}
while (linkList1 != null) {
cur.next = linkList1;
linkList1 = linkList1.next;
cur = cur.next;
}
while (linkList2 != null) {
cur.next = linkList2;
linkList2 = linkList2.next;
cur = cur.next;
}
return head.next;
}
public static void main(String[] args) {
LinkList head = new LinkList(0);
LinkList first = new LinkList(4);
LinkList second = new LinkList(5);
LinkList third = new LinkList(6);
LinkList fourth = new LinkList(7);
head.next = first;
first.next = second;
second.next = third;
third.next = fourth;
fourth.next = null;
LinkList head1 = new LinkList(3);
LinkList first1 = new LinkList(6);
LinkList second1 = new LinkList(10);
LinkList third1 = new LinkList(12);
LinkList fourth1 = new LinkList(14);
head1.next = first1;
first1.next = second1;
second1.next = third1;
third1.next = fourth1;
fourth1.next = null;
LinkList[] list = new LinkList[3];
list[0] = head1;
list[1] = head;
LinkList linkList = mergerLinkList(list);
System.out.println(linkList);
}