题目:输入一个链表,输出链表中倒数第k个结点,为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第一个结点。例如,一个链表有6个结点,从头结点开始,它们的值依次是1、2、3、4、5、6.这个链表的倒数第三个结点是值为4的结点。
示例:输入1 -> 2 -> 3 -> 4 -> 5和k=2; 输出: 4 -> 5
考点:代码的鲁棒性
算法:1、初始化:前指针former,后指针latter;两个指针均指向头结点
2、构建双指针距离:前指针向前移动k-1步。
3、双指针移动:从第k步开始,两个指针一起向前移动,直至former指向尾结点。
4、返回值:返回latter即可。
时间复杂度O(N):N为链表长度,former向前走了N-1步,latter向前走了N-k步。
空间复杂度O(1):双指针former, latter使用常数大小的空间。
根据以上算法,我们可以写出以下代码:
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def getKthFromEnd(self, head: ListNode, k: int) -> ListNode: former = latter = head for _ in range(k-1): former = former.next while former.next: latter, former = latter.next, former.next return latter
但上述代码的鲁棒性是不够的,存在三个问题:
- 链表为空时。由于代码会访问空指针指向的内存,从而造成程序的崩溃
- 输入的参数k=0;同样会造成程序的崩溃
- 链表的结点个数小于k。同样会存在访问空指针指向的内存而造成程序的崩溃的问题;
改进代码:
# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val = x # self.next = None class Solution: def getKthFromEnd(self, head: ListNode, k: int) -> ListNode: # 空链表 if not head: return head # k = 0 if k == 0: return None former = latter = head for _ in range(k-1): # k > 链表长度 if former.next is not None: former = former.next else: return None while former.next: latter, former = latter.next, former.next return latter