快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢。例如可以让快指针每次沿链表向前移动2次,慢指针每次向前移动1次。
如果我们要在上图链表中 删除value为10的节点,只需要设置两个指针,每一次移动后,快指针都会比慢指针多走一个节点,这就能形成一个指针间的差值,通过这个差值,来断开或者链接指针域,从而达到需要的结果。
思路:
设一个快指针 fast,设一个慢指针slow,假定快指针每次移动速度是慢指针的两倍,当快指针到达尾部节点指向None时,慢指针则处于链表的中间节点,从而确定中间节点的值。
图示:
slow与fast指针都指向链表第一个节点,然后slow每次移动一个指针,fast每次移动两个指针。
代码示例:
class ListNode:
def __init__(self, x, next=None):
self.val = x
self.next = next
class Solution:
def deleteNode(self, head: ListNode):
slow = head # 慢指针
fast = head # 快指针
while fast and fast.next:
slow = slow.next
fast = fast.next.next
print(slow.val)
if __name__ == '__main__':
a = ListNode(14, ListNode(23, ListNode(10, ListNode(35, ListNode(56, ListNode(59,ListNode(12,)))))))
obj = Solution()
Node = obj.deleteNode(a)
# 结果为 35
思路:
1、删除倒数第n个节点,意味着需要获得 n-1的指针域以及n的指针域。
2、设置快慢两个指针,先让快指针先走n+1步,然后再和慢指针一起走,当快指针为None时,慢指针刚好停留在 n-1的位置。
图示:
代码实例:
# 快慢指针
class ListNode:
def __init__(self, x, next=None):
self.val = x
self.next = next
class Solution:
def kthToLast(self, head: ListNode, k: int) -> int:
slow = head # 慢指针
fast = head # 快指针
while k+1 > 0:
fast = fast.next
k -= 1
while fast.next is not None:
fast = fast.next
slow = slow.next
slow.next = slow.next.next
while head is not None:
print(head.val)
head = head.next
if __name__ == '__main__':
a = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5,)))))
obj = Solution()
Node = obj.kthToLast(a, 2)
# 结果为 1,2,4,5
思路:
快慢指针中,因为每一次移动后,快指针都会比慢指针多走一个节点,所以他们之间在进入环状链表后,不论相隔多少个节点,慢指针总会被快指针赶上并且重合,此时就可以判断必定有环。
图示:
如果fast指针遍历出None,则说明没有环。
当slow指针和falst指针相同,则说明环有节点。
代码示例:
class Node:
def __init__(self, val, next=None):
self.val = val
self.next = next
def findbeginofloop(head):
slow = head # 慢指针
fast = head # 快指针
if head is None: # 判断链表是否为空
return head
while fast.next != None and fast.next.next != None: # fastPtr的下一个节点和下下个节点都不为空
slow = slow.next
fast = fast.next.next
if slow == fast: # 两个指针相遇存在环结构
print("存在环结构")
break
if __name__ == "__main__":
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
node4 = Node(4)
node5 = Node(5)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node2
findbeginofloop(node1)