在数据结构中,单链表是一种常见的线性数据结构,其由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在 LeetCode 上,单链表相关的问题种类繁多,例如反转链表、合并两个链表、寻找链表的中间节点等。在本篇文章中,我们将深入探讨一些经典的单链表解法,并通过代码示例来加深理解。

1. 反转链表

反转链表是一个经典问题。给定一个单链表的头节点,将链表反转,并返回反转后的链表头节点。

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode current = head;

    while (current != null) {
        ListNode nextTemp = current.next; // 保存下一个节点
        current.next = prev; // 反转当前节点的指针
        prev = current; // 移动 prev 和 current 指针
        current = nextTemp;
    }
    return prev; // prev 将是反转后链表的头节点
}

2. 合并两个有序链表

这个问题要求我们将两个已排序的链表合并成一个新的有序链表。可以利用一个虚拟头节点来简化链表操作。

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode dummy = new ListNode(0); // 虚拟头节点
    ListNode current = dummy;

    while (l1 != null && l2 != null) {
        if (l1.val < l2.val) {
            current.next = l1;
            l1 = l1.next;
        } else {
            current.next = l2;
            l2 = l2.next;
        }
        current = current.next; // 移动当前指针
    }

    if (l1 != null) {
        current.next = l1; // 连接剩余的链表
    } else {
        current.next = l2;
    }

    return dummy.next; // 返回合并后的链表头节点
}

3. 检测链表环

循环链表是链表中的一个重要概念。用快慢指针的方法可以有效地判断一个链表是否存在环。

public boolean hasCycle(ListNode head) {
    if (head == null) return false;

    ListNode slow = head;
    ListNode fast = head;

    while (fast != null && fast.next != null) {
        slow = slow.next; // 慢指针每次走一步
        fast = fast.next.next; // 快指针每次走两步

        if (slow == fast) { // 如果相遇,说明有环
            return true;
        }
    }
    return false; // 没有环
}

4. 找到链表的中间节点

这个问题要求我们找到链表的中间节点,可以使用快慢指针的方法,慢指针每次走一步,快指针每次走两步。

public ListNode middleNode(ListNode head) {
    ListNode slow = head;
    ListNode fast = head;

    while (fast != null && fast.next != null) {
        slow = slow.next; // 慢指针每次走一步
        fast = fast.next.next; // 快指针每次走两步
    }
    return slow; // 当快指针到达链表尾部时,慢指针正好到达中间节点
}

总结

以上是一些常见的单链表问题及其解决方案,这些问题在面试和算法竞赛中经常出现。掌握这些基本的链表操作不仅可以帮助我们解决许多问题,还能够提高我们的编程能力和思维方式。在解决链表问题时,理解链表的结构以及指针的移动极为重要,这会直接影响到代码的正确性和效率。希望本文能够帮助读者更好地理解单链表及其相关的经典解法。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部