[python 刷题] 19 Remove Nth Node From End of List
题目:
Given the head of a linked list, remove the
nthnode 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, headwhile t:l += 1t = t.nextprev, next = head, head.nextwhile l - n - 1 > 0 and next:prev = prev.nextnext = next.nextn += 1if l == n:return head.nextif not next:prev.next = Nonereturn headprev.next = next.nextreturn head
这么处理一下,其实边界条件挺多的(主要是当 n = 0 和 n = 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 个值是被移除的
这个时候 slow 和 fast 同时进入循环,当 fast 指向空时,slow 也指向了 n - 1 个值:

代码如下:
class Solution:def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:if not head:return headt = ListNode(0, head)slow, fast = t, headwhile n:fast = fast.nextn -= 1while fast:slow = slow.nextfast = fast.nextslow.next = slow.next.nextreturn 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 headt = ListNode(0, head)slow, fast = t, headwhile n - 1:fast = fast.nextn -= 1while fast.next:slow = slow.nextfast = fast.nextslow.next = slow.next.nextreturn t.next
这两个代码从结果上来说是一样的
整体上来说,链表也好、二分搜索也好,这些 +1/-1 的边界条件其实就会影响代码会不会 AC