Java中链表题有哪些

发布时间:2021-11-30 17:31:36 作者:小新
来源:亿速云 阅读:109
# 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. 扩展比较不同语言实现差异

推荐阅读:
  1. 【剑指Offer第三题】从尾到头打印链表
  2. 复杂链表的复制(一道算法题)

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

java

上一篇:Ubuntu搭建Mysql+Keepalived高可用如何实现

下一篇:C/C++ Qt TreeWidget单层树形组件怎么应用

相关阅读

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

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