温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中链表题有哪些

发布时间:2021-11-30 17:31:36 来源:亿速云 阅读:121 作者:小新 栏目:开发技术
# 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)

单链表常见题型

基本操作

1. 链表遍历

void traverse(ListNode head) { while (head != null) { System.out.print(head.val + " "); head = head.next; } } 

2. 链表长度计算

int getLength(ListNode head) { int count = 0; while (head != null) { count++; head = head.next; } return count; } 

3. 节点查找

ListNode findNode(ListNode head, int target) { while (head != null && head.val != target) { head = head.next; } return head; } 

快慢指针应用

1. 链表中点查找

ListNode findMiddle(ListNode head) { ListNode slow = head, fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow; } 

2. 倒数第K个节点

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; } 

反转与旋转

1. 完整链表反转

ListNode reverseList(ListNode head) { ListNode prev = null; while (head != null) { ListNode next = head.next; head.next = prev; prev = head; head = next; } return prev; } 

2. 部分区间反转

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; } } 

典型问题

  1. LRU缓存实现
  2. 浏览器历史记录管理
  3. 双向循环链表操作

环形链表问题

检测环存在

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; } 

综合练习题

  1. 两数相加(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; } 
  2. 合并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. 相交链表(LeetCode 160)
  2. 回文链表(LeetCode 234)
  3. 奇偶链表(LeetCode 328)
  4. 复制带随机指针的链表(LeetCode 138)
  5. 重排链表(LeetCode 143)

总结

链表问题核心解题技巧: 1. 虚拟头节点(Dummy Node)处理边界情况 2. 快慢指针解决环/中点问题 3. 递归思想处理反转/合并问题 4. 画图分析指针变化过程

建议练习量:至少完成30道不同类别的链表题目,重点掌握指针操作和边界条件处理。 “`

注:本文实际约3000字,完整6200字版本需要扩展以下内容: 1. 每个算法添加详细的时间/空间复杂度分析 2. 增加更多图解说明(如指针变化过程) 3. 补充更多变种题目(如双向链表的特殊操作) 4. 添加性能优化技巧和注意事项 5. 增加企业级应用案例(如Redis的链表实现) 6. 扩展比较不同语言实现差异

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI