描述
该题来自于力扣第19题
给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
- 链表中结点的数目为
sz - 1 <=
sz<= 30 - 0 <=
Node.val<= 100 - 1 <=
n<= sz
分析
想找到倒数第n个结点,就相当于找到第sz - n + 1个结点,但是sz不知道,需要一趟遍历整个链表才能获得,这样看来无论如何都需要两遍扫描;还记得找到中点结点的方法吗?快慢指针,一遍扫描即可;这里也可以用类似的想法;比如,现有一链表如下,要删除倒数第2个结点:
1 -> 2 -> 3 -> 4 -> 5 -> 6
如果我们能够让第一个指针p1指向4,那么就可以进行删除操作了;利用快慢指针的想法,第二个指针p2需要指向最后一个结点即6,所以两个指针相差2个结点,如果最开始让p1指向1,p2指向3,然后只需让p1++,p2++直到p2到达最后一个结点,这时p1自然达到了倒数第n个结点了。
所以先让p2指针往右走n步,达到第n+1个结点,然后p1,p2指针同时走动1步,直到p2指针指向sz,这时p1自然会指向sz -n,即要删除结点的父结点位置,然后就可以删除了。当然,还要考虑特殊情况:删除一个结点的时候的特殊处理。或者用一个虚假的头指向链表原有head,这样就不用考虑特殊情况了。
算法
采用双指针法,
1. 初始化p1=head,p2=head
2.
进入循环p2 = p2->next,直到i==n,如果p2==null,表明删除的是头结点,则让head = p1->next退出程序,或则进入3
3.
进入循环p1 = p1->next, p2=p2->next,直到p2->next == null,表明p2已到达最后一个结点,此时让p1->next = p1->next->next
代码
python3
1 | class Solution: |
c++
1 | class Solution { |
java
1 | class Solution { |