5.15 二轮 链表
This commit is contained in:
parent
67697ee1a8
commit
4acf3b868b
88
src/main/java/linkedlist/LRUCache.java
Normal file
88
src/main/java/linkedlist/LRUCache.java
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package linkedlist;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LRUCache {
|
||||||
|
class DLinkedNode {
|
||||||
|
int key;
|
||||||
|
int value;
|
||||||
|
DLinkedNode prev;
|
||||||
|
DLinkedNode next;
|
||||||
|
public DLinkedNode() {}
|
||||||
|
public DLinkedNode(int _key, int _value) {key = _key; value = _value;}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Integer, DLinkedNode> cache = new HashMap<>();
|
||||||
|
private int size;
|
||||||
|
private int capacity;
|
||||||
|
private DLinkedNode head, tail;
|
||||||
|
|
||||||
|
public LRUCache(int capacity) {
|
||||||
|
this.size = 0;
|
||||||
|
this.capacity = capacity;
|
||||||
|
// 使用伪头部和伪尾部节点
|
||||||
|
head = new DLinkedNode();
|
||||||
|
tail = new DLinkedNode();
|
||||||
|
head.next = tail;
|
||||||
|
tail.prev = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int get(int key) {
|
||||||
|
DLinkedNode node = cache.get(key);
|
||||||
|
if (node == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// 如果 key 存在,先通过哈希表定位,再移到头部
|
||||||
|
moveToHead(node);
|
||||||
|
return node.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(int key, int value) {
|
||||||
|
DLinkedNode node = cache.get(key);
|
||||||
|
if (node == null) {
|
||||||
|
// 如果 key 不存在,创建一个新的节点
|
||||||
|
DLinkedNode newNode = new DLinkedNode(key, value);
|
||||||
|
// 添加进哈希表
|
||||||
|
cache.put(key, newNode);
|
||||||
|
// 添加至双向链表的头部
|
||||||
|
addToHead(newNode);
|
||||||
|
++size;
|
||||||
|
if (size > capacity) {
|
||||||
|
// 如果超出容量,删除双向链表的尾部节点
|
||||||
|
DLinkedNode tail = removeTail();
|
||||||
|
// 删除哈希表中对应的项
|
||||||
|
cache.remove(tail.key);
|
||||||
|
--size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 如果 key 存在,先通过哈希表定位,再修改 value,并移到头部
|
||||||
|
node.value = value;
|
||||||
|
moveToHead(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToHead(DLinkedNode node) {
|
||||||
|
node.prev = head;
|
||||||
|
node.next = head.next;
|
||||||
|
head.next.prev = node;
|
||||||
|
head.next = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeNode(DLinkedNode node) {
|
||||||
|
node.prev.next = node.next;
|
||||||
|
node.next.prev = node.prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void moveToHead(DLinkedNode node) {
|
||||||
|
removeNode(node);
|
||||||
|
addToHead(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DLinkedNode removeTail() {
|
||||||
|
DLinkedNode res = tail.prev;
|
||||||
|
removeNode(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
40
src/main/java/linkedlist/Partition.java
Normal file
40
src/main/java/linkedlist/Partition.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package linkedlist;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 题目: 86. 分隔链表 (partition)
|
||||||
|
* 描述:给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。
|
||||||
|
* 你应当 保留 两个分区中每个节点的初始相对位置。
|
||||||
|
|
||||||
|
示例 1:
|
||||||
|
输入:head = [1,4,3,2,5,2], x = 3
|
||||||
|
输出:[1,2,2,4,3,5]
|
||||||
|
|
||||||
|
* 链接:https://leetcode.cn/problems/partition-list/
|
||||||
|
*/
|
||||||
|
public class Partition {
|
||||||
|
public ListNode partition(ListNode head, int x) {
|
||||||
|
// 虚拟头
|
||||||
|
ListNode smallDummy = new ListNode(0), largeDummy = new ListNode(0);
|
||||||
|
ListNode small = smallDummy, large = largeDummy;
|
||||||
|
|
||||||
|
// 一次遍历,分拆到两条链
|
||||||
|
while (head != null) {
|
||||||
|
if (head.val < x) {
|
||||||
|
small.next = head;
|
||||||
|
small = small.next;
|
||||||
|
} else {
|
||||||
|
large.next = head;
|
||||||
|
large = large.next;
|
||||||
|
}
|
||||||
|
head = head.next;
|
||||||
|
}
|
||||||
|
// 断开“>=x”链尾,避免环
|
||||||
|
large.next = null;
|
||||||
|
// 拼接两部分
|
||||||
|
small.next = largeDummy.next;
|
||||||
|
|
||||||
|
return smallDummy.next;
|
||||||
|
}
|
||||||
|
}
|
13
src/main/java/linkedlist/ReverseKGroup.java
Normal file
13
src/main/java/linkedlist/ReverseKGroup.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package linkedlist;
|
||||||
|
/**
|
||||||
|
* 题目: 82. 删除排序链表中的重复元素 II (deleteDuplicates)
|
||||||
|
* 描述:给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
|
||||||
|
|
||||||
|
示例 2:
|
||||||
|
输入:head = [1,2,3,3,4,4,5]
|
||||||
|
输出:[1,2,5]
|
||||||
|
|
||||||
|
* 链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-list-ii/
|
||||||
|
*/
|
||||||
|
public class ReverseKGroup {
|
||||||
|
}
|
44
src/main/java/linkedlist/RotateRight.java
Normal file
44
src/main/java/linkedlist/RotateRight.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package linkedlist;
|
||||||
|
/**
|
||||||
|
* 题目: 61. 旋转链表 (rotateRight)
|
||||||
|
* 描述:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
|
||||||
|
|
||||||
|
示例 1:
|
||||||
|
输入:head = [1,2,3,4,5], k = 2
|
||||||
|
输出:[4,5,1,2,3]
|
||||||
|
|
||||||
|
* 链接:https://leetcode.cn/problems/rotate-list/
|
||||||
|
*/
|
||||||
|
public class RotateRight {
|
||||||
|
public ListNode rotateRight(ListNode head, int k) {
|
||||||
|
if (head == null || head.next == null || k == 0) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
// 1. 先遍历一遍,求长度并连接成环
|
||||||
|
ListNode tail = head;
|
||||||
|
int n = 1;
|
||||||
|
while (tail.next != null) {
|
||||||
|
tail = tail.next;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
// 如果 k 对 n 取余后是 0,旋转后还是原链表
|
||||||
|
int r = k % n;
|
||||||
|
if (r == 0) {
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
tail.next = head; // 形成环
|
||||||
|
|
||||||
|
// 2. 找到新尾:走 (n - r - 1) 步
|
||||||
|
int stepsToNewTail = n - r;
|
||||||
|
ListNode newTail = head;
|
||||||
|
for (int i = 1; i < stepsToNewTail; i++) {
|
||||||
|
newTail = newTail.next;
|
||||||
|
}
|
||||||
|
// 3. 新头是新尾的下一个节点
|
||||||
|
ListNode newHead = newTail.next;
|
||||||
|
// 4. 断开环
|
||||||
|
newTail.next = null;
|
||||||
|
|
||||||
|
return newHead;
|
||||||
|
}
|
||||||
|
}
|
13
src/test/java/linkedlist/PartitionTest.java
Normal file
13
src/test/java/linkedlist/PartitionTest.java
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package linkedlist;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class PartitionTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void partition() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user