返回

LeetCode 21:剑指 Offer 22 - 链表中倒数第 k 个节点,从 1 开始计数

前端

大家好,我是 LeetCode 刷题的忠实爱好者,今天我们将一起解决 LeetCode 21:剑指 Offer 22 - 链表中倒数第 k 个节点 这道题目。这道题要求我们从一个链表中找到倒数第 k 个节点,这对于链表操作的理解和算法实现能力都是一个不错的考验。我们从题目的要求入手,逐步剖析解题思路和代码实现。

题目要求

给你一个链表,输出该链表中倒数第 k 个节点。为了符合大多数人的习惯,本题从 1 开始计数,即链表的尾节点是倒数第 1 个节点。

例如:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

解题思路

为了找到链表中倒数第 k 个节点,我们可以使用两种主要的思路:

  1. 双指针法 :使用两个指针同时遍历链表,其中一个指针先走 k 步,然后两个指针同时遍历,直到先走的指针到达链表末尾。此时,后一个指针所指向的节点就是倒数第 k 个节点。

  2. 一次遍历法 :从头开始遍历链表,并记录链表的长度。然后,从链表尾部开始遍历,走到链表的长度减去 k 的位置,此时所指向的节点就是倒数第 k 个节点。

代码实现

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        # 双指针法
        fast = head
        slow = head
        # 先让快指针走 k 步
        for _ in range(k):
            fast = fast.next
        # 然后两个指针同时遍历
        while fast:
            fast = fast.next
            slow = slow.next
        # slow 指向倒数第 k 个节点
        return slow

    def getKthFromEnd2(self, head: ListNode, k: int) -> ListNode:
        # 一次遍历法
        length = 0
        cur = head
        # 计算链表长度
        while cur:
            length += 1
            cur = cur.next
        # 从链表尾部开始遍历
        cur = head
        for _ in range(length - k):
            cur = cur.next
        # cur 指向倒数第 k 个节点
        return cur

复杂度分析

  • 时间复杂度:两种方法的时间复杂度都是 O(n),其中 n 是链表的长度。

  • 空间复杂度:两种方法的空间复杂度都是 O(1),因为我们没有使用额外的空间来存储链表中的节点。

总结

通过这道题的讲解,我们学习了两种不同的方法来找到链表中倒数第 k 个节点。双指针法和一次遍历法各有优缺点,具体使用哪种方法取决于实际情况。我希望这个题解对你有帮助,也希望你能继续关注我的 LeetCode 刷题系列文章,我们一起学习,共同进步!