19. 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:
你能尝试使用一趟扫描实现吗?
这道题难点是在要一趟遍历实现这个结果,多时间复杂度上有明确的要求,但是在空间复杂度上没有时间要求,所以我么可以多定义几个变量来实现,下面是Python实现的代码。
# -*- coding: utf-8 -*- # Time : 2018/4/1 8:58 # Author : Andy # File : remove_list_end.py # Software: PyCharm class ListNode: def __init__(self, x): self.val = x self.next = None class Solution: def removeNthFromEnd(self, head, n): p = head p1 = ListNode(-1) p1.next = head head = p1 for i in range(0,n): p = p.next while p != None: p1 = p1.next p = p.next p1.next = p1.next.next return head.next if __name__=="__main__": s = Solution () head = ListNode(-1) p = head node = [1,2,3,4,5,6,7,8,9] n = 3 for i in node: a = ListNode(i) p.next = a p = p.next p = s.removeNthFromEnd(head.next,n) while not p == None: print(p.val) p = p.next
代码中有两点是整个算法的关键处:
1、一次遍历,利用两个指针从左到右依次遍历,一个在前一个在后,两个指针之间的差距是n,这样在前面一个指针便利到最后的时候就会出现第一个指针在整个链表的倒数第n个节点的前面的位置(为什么会这样看第二条)。这样就可以删除第n个节点了。
2、这两个指针的初始地址不是在一起的,后面一个指针p指向head,而p1指针是重新定义的一个节点,这个节点的next指向p。这样就能够实现p1是p节点的前面一个节点。
3、最后返回的是head节点的next。
总的来说是,系统给的链表没有头结点,我们自己定义一个头结点然后返回头结点的next。