通过设置快、慢两个指针,可以通过一次遍历得到单向链表的倒数第K个节点。
但两个问题有着较为明显的区别:
(1)对于寻找倒数第K个节点,慢指针慢于快指针第K-1步前进。
(2)对于删除倒数第K个节点,为了保证得到删除节点父节点的信息,慢指针要慢于快指针第K步前进。
(3)两者均要注意当链表长度不足时边界条件的定义。对于删除问题,尤其要注意删除第一个元素(倒数第N个)时,链表head指针的调整。
# 定义单向链表
class Node(object):
def __init__(self, value):
self.value = value
self.next = None
def __repr__(self):
return f'Node({self.value})'
class LinkList(object):
def __init__(self):
self.head = None
def __repr__(self):
if not self.head:
return None
nodelist = []
node = self.head
while node:
nodelist.append(f"Node({node.value})")
node = node.next
return "-->".join(nodelist)
def add_rear(self, value):
if not self.head:
self.head = Node(value)
else:
node = self.head
while node.next:
node = node.next
node.next = Node(value)
1. 寻找倒数第K个节点
def findLastK(head:[None, Node], K):
"""
head: 头指针
K:倒数第K个
"""
if head is None or K <= 0:
return None
ahead, bhead = head, head # type: Node, 快、慢指针初始均指向链表头指针
for i in range(K-1):
ahead = ahead.next
if ahead is None:
return None
while ahead.next:
ahead = ahead.next
bhead = bhead.next
return bhead
2. 删除倒数第K个节点
def delLastK(linkList:[None, LinkList], K):
if linkList is None or K <= 0:
return None
ahead, bhead = linkList.head, linkList.head # type: Node, 快、慢指针初始值均为链表的头指针
for i in range(K): # 快指针领先K步
if ahead is None:
return None
ahead = ahead.next
if ahead is None: # 边界条件,此时删除链表第一个元素,head指针需要重新设定
linkList.head = bhead.next
else:
while ahead.next: # 删除节点的父节点直接指向删除节点的子节点
ahead = ahead.next
bhead = bhead.next
bhead.next = bhead.next.next
return linklist