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

题目:

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

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

这里提供的 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

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

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

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

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

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

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

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

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

代码如下:

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

这里取 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/-1 的边界条件其实就会影响代码会不会 AC

10-19 13:18