LeetCode19. 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def removeNthFromEnd(self, head, n):
"""
:type head: ListNode
:type n: int
:rtype: ListNode
"""
dummy = ListNode(0)
dummy.next = head
fast = slow = dummy
# 相差 n-1 步,所以最后删除slow.next,不是slow
for _ in range(n):
fast = fast.next
while fast and fast.next:
fast = fast.next
slow = slow.next
# 删除slow.next
slow.next = slow.next.next
return dummy.next
剑指22:(返回)链表中倒数第k个节点
输入一个链表,输出该链表中倒数第k个结点。
注意代码鲁棒性,三种特殊情况要考虑到
如果在只希望一次遍历的情况下, 寻找倒数第k个结点, 可以设置两个指针
第一个指针先往前走k-1步, 然后从第k步开始第二个指针指向头结点
然后两个指针一起遍历
当地一个指针指向尾节点的时候, 第二个指针正好指向倒数第k个结点
推广: 寻找中间节点, 两个指针一起, 第一个指针每次走两步, 第二个指针每次走一步, 快指针指到尾部, 慢指针正好指到中间
代码双指针
# -*- coding:utf-8 -*-
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def FindKthToTail(self, head, k):
# 防止头指针为空,或k无意义
if head == None or k <= 0:
return None
# 快慢指针:实现仅一次遍历链表
pAhead = head
pBehind = head
# 先让快指针前进k-1步
for i in range(k-1):
# 防止节点数少于k,造成访问空指针
if pAhead.next != None:
pAhead = pAhead.next
else:
return None # 节点数少于k
while pAhead.next != None:
pAhead = pAhead.next
pBehind = pBehind.next
return pBehind
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node1.next = node2
node2.next = node3
node3.next = node4
S = Solution()
print(S.FindKthToTail(node1, 5).val)