找出链表中倒数第K个节点

今天来看一道有意思的链表算法题目。python

给到一个单向链表,要求找出该链表中倒数第 k >个节点,要求只能遍历一次链表,且空间复杂度为 O(1)。算法

思路1:若是能从链表尾部开始遍历,那只需倒序遍历 k 个节点便是要找出的节点,可是因为是单链表,只能从头结点开始遍历。数组

思路2:先遍历一遍该单链表,获取链表的总节点数 n,那么第 n-k+1 这个节点就是倒数第 k 个节点。因此第二次再遍历到第 n-k+1 这个节点便可,可是题目要求只能遍历一遍链表。spa

思路3:经过遍历该链表把节点都存入到一个数组中,而后再经过数组下标可直接获取到倒数第 k 个节点,可是这样会须要额外的存储空间,空间复杂度为 O(n)。指针

上面这三种常规思路其实都是不符合题目要求的,那就只能想其余办法了。code

咱们知道,链表的节点之间都是经过指针来链接的,咱们先额外定义两个空指针,分别叫前指针和后指针。cdn

先让前指针指向链表的头指针并开始遍历,一直遍历到第 k-1 个节点,在这期间,后指针原地保持不动。blog

当前指针遍历到第 k 个节点时,后指针也指向链表头指针并开始遍历,在这以后,前指针每日后遍历一个节点,后指针也日后遍历一个节点。utf-8

这样先后两指针的距离始终都保持为 k-1,当前指针遍历到链表的最后一个节点时,后指针恰好也就到了倒数第 k 个节点了。it

若是还没想明白的话,看下面的图应该就很好理解了。p1 表明前指针,p2 表明后指针,该链表一共有 6 个节点,要求的是倒数第 3 个节点。

固然这只是题目的解决思路,实际用代码来实现这个算法,还有一些须要特别注意的地方。

好比头指针不能为空,k 不能等于 0,k 不能大于链表的总节点数。这些都是须要咱们在代码中考虑到的状况,下面附上一份用 python 实现该算法的代码。

# -*- coding:utf-8 -*-

#链表节点的定义
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        #若是头指针为空或k为0 直接返回none
        if head == None:
            return None
        if k == 0:
            return None

        pAhead = pBehind = head
        # 快指针先走k步
        for i in range(k):
            #若是k大于链表长度,返回空
            if pAhead == None:
                return None
            #继续日后遍历
            pAhead = pAhead.next
        #快慢指针同时日后遍历
        while pAhead != None:
            pAhead = pAhead.next
            pBehind = pBehind.next
        return pBehind
复制代码

有问题欢迎留言交流,如文章对你有帮助,就点个赞哈,感谢支持。

相关文章
相关标签/搜索