19.删除链表的倒数第N个结点

在这里插入图片描述

我的思路就是先遍历一遍获得总长度,将倒数第N结点,换成正数的第m = len - n + 1个结点,然后从头遍历到第m个结点,删除即可。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:

        if head.next == None: # 特殊情况1:长度为1
            return None

        # 长度>=2
        q = head.next
        pre = head
        Llen = 2
        # 获得链表的长度
        while q.next:
            Llen += 1
            pre = q # 记录前一个节点
            q = q.next # 后移
        # pre 指向倒数第二个节点,q指向最后一个节点

        m = Llen - n + 1 # 删除正数第m个数
        
        if m == Llen: # 特殊情况2:删除最后一个数 ,n=1
            pre.next = None
            # 删除节点p
            return head
        
        if m == 1: # 特殊情况3:删除第一个数,n=Len # 删除第一个节点
            head = head.next
            return head

        # 情况4:删除中间节点
        count = 1
        q = head.next
        pre = head
        while q:
            count += 1
            if count == m:
                pre.next = q.next
                # 删除q
            pre = q
            q = q.next
        
        return head
        

但如果要求只遍历一遍,怎么实现呢?
可以参考官方的解析用栈或者两个指针。

在这里插入图片描述
我觉得栈应该也算两次遍历

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        # 比我的代码简洁多了,而且还通用。引入dummy作为头指针的前驱指针
        dummy = ListNode(0,head) # 头指针的前一个指针
        stack = list() # 栈
        cur = dummy
        while cur: # 全部遍历入栈
            stack.append(cur)
            cur = cur.next

        for i in range(n): # 计数出栈
            stack.pop() # 弹出n个后,此时顶端是倒数第n个指针的前一个指针,为了方便删除操作
        
        prev = stack[-1] 
        prev.next = prev.next.next
        return dummy.next
        

用双指针才算只遍历一次

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dummy = ListNode(0,head)
        first = head # 用来判断是否到最后一个结点
        second = dummy # 用来方便删除操作

        for i in range(n): # 第一个指针先走n步后,第二个再跟上,保持n的距离
            first = first.next

        while first: # 一起走,第一个指针走到尽头就停止,此时第二个指针指向该删除结点的前一个指针
            first = first.next
            second = second.next
        
        second.next = second.next.next # 删除结点
        return dummy.next
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值