剑指offer(python)--题目14-链表中倒数第k个节点

题目描述
输入一个链表,输出该链表中倒数第k个结点。
思路:为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。假设一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。
在这里插入图片描述
在文中节点的定义是data,和next域,说明这是一个单链表,只有一个指针

想法一;

为了得到倒数第k个结点,很自然的想法是先走到链表的尾端,再从尾端回溯k步。当时,从链表结点的定义可以看出本题中的链表是单向链表,单向链表的结点只有从前往后的指针而没有从后往前的指针,因此这种思路行不通,它只适用于双向链表。

一不可行

想法二,
假设整个链表有n个结点,那么倒数第k个结点就是从头结点开始的第n-k+1个结点。如果我们能够得到链表中结点的个数n,那我们只要从头结点开始往后走n-k+1步就可以了。
  那么,这里的重点就在于如何求链表中节点的个数n,只需要从头开始遍历链表,每经过一个结点,计数器加1就行了。
  但是,问题来了:这种思路需要遍历链表两次,第一次统计出链表中结点的个数,第二次才能找到倒数第k个结点。
先遍历链表,算出链表节点数count,第二次直接遍历到第count-k个节点。但是要注意,可能链表结点数cout小于k,此时要返回NULL。这一条件要先判断

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        if  k<=0 or head==None:
            return None
        count=0
        p=head
        while p!=None:
            count+=1 # 算出链表节点数
            p=p.next
        if k>count:
            return None
        number=count-k+1  #需要走的步数
        cnt=0
        p=head
        while p!=None:
            cnt=cnt+1
            if cnt==number:
                return p
            p=p.next

好像速度更快

**思路3:可以用两个指针,一个指针遍历到第k个结点的时候,第二个指针再走到第一个节点,然后两个指针的距离始终保持k-1,这样,当第一个指针的next==NULL,也就是走到最后一个节点的时候,第二个指针对应的位置,就是倒数第k个结点。
这样的好处是能够节省一个循环,时间复杂度会相应降低。从Q(2N) 到Q(N)


为了能够只遍历一次就能找到倒数第k个节点,可以定义两个指针:

(1)第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动;

(2)从第k步开始,第二个指针也开始从链表的头指针开始遍历;

(3)由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。
  注意,但是需要一个小循环让第一个指针先走到第k个指针。同时也存在结点总数小于k的问题,如果循环还没有进行到k次,而第一个指针的已经是NULL,即走到头了,那么,函数返回NULL。
  
**

技巧:当我们用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针来遍历链表。可以让其中一个指针遍历的速度快一些(比如一次在链表上走两步),或者让它先在链表上走若干步。

https://blog.csdn.net/honeyaya/article/details/52872104

**

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def FindKthToTail(self, head, k):
        if k<=0 or head==None:
            return None
        else:
            count=0
            p=head
            mark=False
            ans=head #第二个指针
            while p!=None:
                count=count+1
                if count>k:
                    ans=ans.next
                p=p.next
            if count<k:
                ans=None
            return ans

猜你喜欢

转载自blog.csdn.net/qq_24429333/article/details/87866115