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