双指针
双指针分为左右指针和快慢指针
快慢指针
主要解决的是链表中的问题,典型的是链表中是否有环。
初始化指向的链表头结点head 前进时快指针fast在前,慢指针slow在后面
1、判断链表中是否有环
链表中没有环指针最后会指向null表示链表到头了,采用快慢指针,如果不含有环,fast最终会等于null,表示其不含环;如有环,fast最后会超过慢指针一圈,即fast==slow,表示有环。
leetcode141环形链表
class Solution:
def hasCycle(self, head: Optional[ListNode]) -> bool:
fast = head
slow = head
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
if fast == slow: return True
return False
2、已知链表中有环,返回环的起始位置
这种情况是当快慢指针相遇的时候,让其中指针指回头结点,然后两指针的前进速度相同前进,但两指针再次相遇的时候,这个位置就是环开始的位置。
原理是:fast比slow多一倍,也就是当slow走了K步,fast则是2k步,此时,slow在回到head的位置,假如相遇点距离环起点的距离是m,则head到环起点的位置是k-m,因为环的长度是k,那么fast再走k-m就到环起点了
class Solution:
def detectCycle(self, head: Optional[ListNode]) -> bool:
fast = slow = head
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
if fast == slow:
return;
slow = head
while slow != fast:
fast = fast.next
slow = slow.next
return slow
3、寻找链表的中点
fast 一次前进两步,slow一次前进一步,当fast到达链表的尽头,慢指针就在链表的中间位置
leetcode876 链表中间结点
class Solution:
def middleNode(self, head: ListNode) -> ListNode:
fast = slow = head
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
return slow
4、寻找链表的倒数第n个元素
leetcode19 删除链表的倒数第n个元素
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
fast = slow = head
# fast先前进n步
while n > 0:
fast = fast.next
n -= 1
if fast == None:#如果fast是null的时候,此时倒数第n个节点就是第一个节点
return head.next
while fast != None and fast.next != None:
fast = fast.next
slow = slow.next
slow.next = slow.next.next#删除节点的操作
return head
学习内容来自labuladong算法