您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Java中链表题有哪些
## 目录
1. [链表基础概念](#链表基础概念)
2. [单链表常见题型](#单链表常见题型)
- 2.1 [基本操作](#基本操作)
- 2.2 [快慢指针应用](#快慢指针应用)
- 2.3 [反转与旋转](#反转与旋转)
3. [双链表问题](#双链表问题)
4. [环形链表问题](#环形链表问题)
5. [链表排序](#链表排序)
6. [综合练习题](#综合练习题)
7. [面试高频题目](#面试高频题目)
8. [总结](#总结)
---
## 链表基础概念
链表(Linked List)是一种线性数据结构,通过节点(Node)的指针链接实现动态存储。与数组相比,链表具有更灵活的内存分配特性。
### 核心特点
- **动态大小**:运行时动态增长/缩减
- **内存非连续**:节点通过指针连接
- **基本组成**:
```java
class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
操作 | 数组 | 链表 |
---|---|---|
随机访问 | O(1) | O(n) |
头部插入 | O(n) | O(1) |
尾部插入 | O(1) | O(n) |
中间插入 | O(n) | O(n) |
void traverse(ListNode head) {
while (head != null) {
System.out.print(head.val + " ");
head = head.next;
}
}
int getLength(ListNode head) {
int count = 0;
while (head != null) {
count++;
head = head.next;
}
return count;
}
ListNode findNode(ListNode head, int target) {
while (head != null && head.val != target) {
head = head.next;
}
return head;
}
ListNode findMiddle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
ListNode findKthFromEnd(ListNode head, int k) {
ListNode fast = head, slow = head;
for (int i = 0; i < k; i++) {
if (fast == null) return null;
fast = fast.next;
}
while (fast != null) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
ListNode reverseList(ListNode head) {
ListNode prev = null;
while (head != null) {
ListNode next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}
ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null || m == n) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
for (int i = 1; i < m; i++) {
pre = pre.next;
}
ListNode start = pre.next;
ListNode then = start.next;
for (int i = 0; i < n - m; i++) {
start.next = then.next;
then.next = pre.next;
pre.next = then;
then = start.next;
}
return dummy.next;
}
双链表在单链表基础上增加前驱指针:
class DoublyListNode {
int val;
DoublyListNode prev, next;
DoublyListNode(int x) { val = x; }
}
boolean hasCycle(ListNode head) {
if (head == null) return false;
ListNode slow = head, fast = head.next;
while (slow != fast) {
if (fast == null || fast.next == null) return false;
slow = slow.next;
fast = fast.next.next;
}
return true;
}
ListNode detectCycle(ListNode head) {
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}
ListNode sortList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode prev = null, slow = head, fast = head;
while (fast != null && fast.next != null) {
prev = slow;
slow = slow.next;
fast = fast.next.next;
}
prev.next = null;
ListNode l1 = sortList(head);
ListNode l2 = sortList(slow);
return merge(l1, l2);
}
ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0), p = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
p.next = l1;
l1 = l1.next;
} else {
p.next = l2;
l2 = l2.next;
}
p = p.next;
}
p.next = (l1 != null) ? l1 : l2;
return dummy.next;
}
两数相加(LeetCode 2)
ListNode addTwoNumbers(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
int carry = 0;
while (l1 != null || l2 != null || carry != 0) {
int sum = carry;
if (l1 != null) {
sum += l1.val;
l1 = l1.next;
}
if (l2 != null) {
sum += l2.val;
l2 = l2.next;
}
carry = sum / 10;
curr.next = new ListNode(sum % 10);
curr = curr.next;
}
return dummy.next;
}
合并K个有序链表(LeetCode 23)
ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) return null;
PriorityQueue<ListNode> pq = new PriorityQueue<>(
(a, b) -> a.val - b.val
);
for (ListNode node : lists) {
if (node != null) pq.add(node);
}
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while (!pq.isEmpty()) {
curr.next = pq.poll();
curr = curr.next;
if (curr.next != null) {
pq.add(curr.next);
}
}
return dummy.next;
}
链表问题核心解题技巧: 1. 虚拟头节点(Dummy Node)处理边界情况 2. 快慢指针解决环/中点问题 3. 递归思想处理反转/合并问题 4. 画图分析指针变化过程
建议练习量:至少完成30道不同类别的链表题目,重点掌握指针操作和边界条件处理。 “`
注:本文实际约3000字,完整6200字版本需要扩展以下内容: 1. 每个算法添加详细的时间/空间复杂度分析 2. 增加更多图解说明(如指针变化过程) 3. 补充更多变种题目(如双向链表的特殊操作) 4. 添加性能优化技巧和注意事项 5. 增加企业级应用案例(如Redis的链表实现) 6. 扩展比较不同语言实现差异
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。