[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, 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