【数据结构与算法】(六)快慢指针法

用途一:查找链表中间节点

示例:

      head->1->2->3->4->5->6->7->None

     结果:中间节点为4

方法:

        定义两个指针,一个快指针,一个慢指针,当快指针遍历到尾节点的时候,慢指针刚好遍历到中间的节点。

       当节点个数为奇数时,中间节点只有一个,当节点个数为偶数时,慢指针指向的节点和它的后继都是中间节点。

      这种办法时间只需要遍历一次,且未开辟新空间,因此时间复杂度为O(n),空间复杂度为O(1)。

代码:

“”“”“”
class LNode():
    def __init__(self,x=None):
        self.data = x
        self.next = None


head = Lnode()                      #默认head的结构为节点
“”“”“”
def FindMiddleNode(head):
    if head == None or head.next == None:
        return head
    fast = head       #快指针
    slow = None       #慢指针
    slowPre = head    #slowPre 用来标记中间节点的第一个节点
    
    while fast != None or fast.next != None:
        slow.pre = slow 
        slow = slow.next                   #slow一次前进一个单位
        fast = fast.next.next              #fast一次前进两个单位
   
    slowPre.next = None                    #从中间节点的前面断开成两个链表
    return slow                            #返回链表的第一个元素(断开的链表没有头)
   
        

用途二:找到链表的倒数第个节点

方法:

        与上面一样,不过这里的移动方式要变一下,之前快慢指针同时起步,slow= slow.next ;fast = fast.next.next,这样做,快指针比慢指针整整快了一倍。

       想要找倒数第k个节点,可以让快指针先行k步,然后两个指针一起往后走,当快指针到达尾节点的时候,慢指针指向的就是前k个节点。

示例:

    head->1->2->3->4->5->6->7->None

     k= 2(倒数第2个节点)

   结果: 倒数第2个节点为6

代码:

def FindLastK(head , k):
    if head == None or head.next == None:
        return head                              #确保链表不为空
        
    slow = LNode()                               定义两个指针
    fast = LNode()

    slow = head.next                             #两个指针的起始位置都为第一个节点
    fast = head.next

    i = 0
    while(i<k and fast != None):                 #快指针先向前走K步
        fast = fast.next
        i+=1
     
    if i<k:                                      #判断k是否超出链表长度                                   
        return None

    while fast != None:                          #只要fast不到尾,就一直走
        slow = slow.next                         #两个指针行进速度一样
        fast = fast.next
    return slow                             

    

用途三:检测单链表是否有环,返回环的入口。

方法: 

        (一)检测单链表是否有环:

        定义两个指针,一个快一个慢,两个指针刚开始时都指向链表的头节点,之后快指针每次前进两步,慢指针每次前进一步,如果他们相遇了(fast= low),说明快指针已经转了一圈回来了,也就说明链表有环。

        (二)返回环的入口:

         同样定义两个指针,一个指向头节点,另一个指向相遇点,两个指针同时向后走,他们的第一次相遇点就是环的入口。

分析:

        就类似于在操场的跑道上跑步,两个人,快的人的速度是慢的人的两倍,跑的快的人,在第二圈会再次与跑的慢的人相遇。

代码:

      

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

(一)检测单链表是否有环:

def isLoop(head):
    if head == None or head.next == None:
        return None
    fast = head
    slow = head                              #刚开始都指向头   或者都指向head.next都可以
    while fast !=None and fast.next !=None:
        slow = slow.next                     #快慢指针前进速度
        fast = fast.next.next
        if slow == fast:
            return slow
        else:
            return None

(二)返回环的入口:

def findLoopNode(head,meetNode):
    first = head
    second = meetNode
    while first != second:
        first = first.next
        second = second.next
    return first

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值