22:链表中倒数第k个节点(剑指offer第2版)+ LeetCode19. 删除链表的倒数第N个节点

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)

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值