返回

掌握LeetCode 876:快准狠地找到链表的中间节点

前端

LeetCode 876. 链表的中间结点


许多软件面试喜欢以算法作为考察标准之一,LeetCode 凭借其丰富且全面的题目和便捷的线上评测服务,成为许多求职者备战面试的利器。在LeetCode题库中,有一道经典的题目 —— 876. 链表的中间结点,现在就让我们踏上寻觅链表中间节点的奇妙旅程。


问题概述


假设你有如下定义的单链表:

struct ListNode {
  int val;
  ListNode *next;
  ListNode() : val(0), next(nullptr) {}
  ListNode(int x) : val(x), next(nullptr) {}
  ListNode(int x, ListNode *next) : val(x), next(next) {}
};

给定链表的头结点 head,你的任务是找到并返回链表的中间结点。如果链表的长度为奇数,则返回中间结点。如果链表的长度为偶数,则返回中间结点的下一个结点。


解决方案


【核心思想】

寻找链表中间节点的方法多种多样,快慢指针法是最常见且最有效的方法之一,它巧妙利用了两个指针的步长差异来快速定位中点。

【算法步骤】

  • 初始化两个指针,慢指针slow和快指针fast,都指向头结点head
  • 对于每个结点,慢指针slow向前移动一步,即 slow = slow->next,而快指针fast向前移动两步,即 fast = fast->next->next
  • 重复上述步骤,直到快指针fast到达链表的末尾(fast == nullptr)。
  • 当快指针fast到达链表末尾时,慢指针slow恰好指向链表的中间结点。
  • 返回慢指针slow指向的结点,即链表的中间结点。

【代码实现】

ListNode* middleNode(ListNode* head) {
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast && fast->next) {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}

【时间复杂度】

快慢指针法的复杂度为 O(n),其中 n 为链表的长度。这是因为该算法需要遍历整个链表一次。


【空间复杂度】

快慢指针法的空间复杂度为 O(1),因为该算法只需要两个指针,而这两个指针的占用空间是固定的。


结语


快慢指针法作为一种高效的链表中间节点查找算法,在LeetCode中得到了广泛的应用。掌握这一算法,可以帮助我们在面试中脱颖而出。想要提升自己的算法能力,不妨多加练习,熟能生巧。LeetCode题库中还有大量精彩的题目等待你去探索,期待你在算法的世界里不断进步,成就辉煌。


更多精彩内容