• [python 刷题] 19 Remove Nth Node From End of List


    [python 刷题] 19 Remove Nth Node From End of List

    题目:

    Given the head of a linked list, remove the nth node from the end of the list and return its head.

    题目说的是就是移除倒数第 n 个结点,如官方给的案例:

    在这里插入图片描述

    这里提供的 n 就是 2,也就是倒数第二个结点

    这道题本身的难度不是很大,最简单的方法就是 2-pass,第一个循环找到链表的长度,随后循环到 n - 2 的长度即可,这个解法代码如下:

    class Solution:
        def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
            l, t = 0, head
            while t:
                l += 1
                t = t.next
    
            prev, next = head, head.next
    
            while l - n - 1 > 0 and next:
                prev = prev.next
                next = next.next
                n += 1
    
            if l == n:
                return head.next
    
            if not next:
                prev.next = None
                return head
    
            prev.next = next.next
    
            return head
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    这么处理一下,其实边界条件挺多的(主要是当 n = 0n = len(linked list) 这两个情况)

    不过这道题有个 follow up:Could you do this in one pass?

    也就是问一个循环能不能解决问题

    这也是一个可以用双指针解决的方法,题目中说 nth from the emd,其实换个方式理解也可以理解成 nth from start:

    在这里插入图片描述

    这个时候的 fast 指向 3,slow 则是指向新建的 head,这里的差是 n + 1 是因为差第 n 个值是被移除的

    这个时候 slowfast 同时进入循环,当 fast 指向空时,slow 也指向了 n - 1 个值:

    在这里插入图片描述

    代码如下:

    class Solution:
        def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
            if not head:
                return head
    
            t = ListNode(0, head)
    
            slow, fast = t, head
            while n:
                fast = fast.next
                n -= 1
    
            while fast:
                slow = slow.next
                fast = fast.next
    
            slow.next = slow.next.next
    
            return t.next
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这里取 n = 1 反而是因为代码实现起来会方便一些,否则就要使用 while n - 1:while fast.next: 结束循环:

    class Solution:
        def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
            if not head:
                return head
    
            t = ListNode(0, head)
    
            slow, fast = t, head
            while n - 1:
                fast = fast.next
                n -= 1
    
            while fast.next:
                slow = slow.next
                fast = fast.next
    
            slow.next = slow.next.next
    
            return t.next
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这两个代码从结果上来说是一样的

    整体上来说,链表也好、二分搜索也好,这些 +1/-1 的边界条件其实就会影响代码会不会 AC

  • 相关阅读:
    BigDecimal 用法总结
    树、二叉树、堆及其应用(堆排序、top-k问题)
    vue部分手写面试题
    MongoDB部署
    【Python 实战基础】Pandas中Series与数据list如何互相转换
    Rockchip PX30/RK3326 Android开机时间优化
    集成学习-树模型
    【操作系统笔记】南京大学jyy老师
    qt5-入门-自定义委托-可编辑的TableModel与信号接收
    Win10电脑怎么更改UEFI固件设置
  • 原文地址:https://blog.csdn.net/weixin_42938619/article/details/133922696