19.删除链表的倒数第N个结点
给你一个链表,删除链表的倒数第 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]
解题思路与代码
之前做过两次这题!也是参考的题解 用的快慢指针 现在居然全忘干净了!让一让二不让三!
【1】我的想法 计算链表长度
虽说这是个双指针专题中的题
但是第一想法还是
【1】求链表长度
【2】根据长度删除节点然后返回头结点
这里可以复习到一个很棒的知识点 也算有收获吧
就是使用虚拟头结点 防止删除结点的时候把第一个结点给删了 到时候返回head 就错了~
要返回
虚拟头结点.next
这种方法相当于是 双重遍历
属于没有想到巧方法(一次遍历解决问题)的情形
Java
代码实现
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
int length = getLength(head);
//下面这里对虚拟头结点的运用还是要学习并熟记的!
ListNode dummyHead = new ListNode(0, head);//相当于 new ListNode(0); dummyHead.next = head;
ListNode cur = dummyHead;
for(int i = 0; i < length - n; i++){
cur = cur.next;
}
cur.next = cur.next.next;
return dummyHead.next;
}
public int getLength(ListNode head){
int length = 0;
while(head != null){
length++;
head = head.next;
}
return length;
}
}
【2】双指针(快慢指针)法
一次遍历解决问题
参考题解 动画图解 LeetCode 第 19 号问题:删除链表的倒数第 N 个节点
这个解法的关键是 ——
快指针q与p间隔为n个结点 且 q指向NULL 时 删除慢指针p的下一个结点即可
感谢大佬给画的动图 没这个图还真不好想啊!
代码
Java
//Java
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummyHead = new ListNode(0);//创建虚拟头结点解决头结点删除的问题(n=链表长度时)
dummyHead.next = head;
ListNode slow = dummyHead;
ListNode fast = dummyHead;
for(int i = 0; i < n + 1; i++){//为了让fast与slow相差n个结点 fast从虚拟头结点开始要走n+1步
fast = fast.next;
}
//while (n-- > 0) {
// fast = fast.next;
//} t
//现在快指针与慢指针距离n个结点
while(fast != null){
//快指针指向null时 慢指针.next为要删除的结点
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummyHead.next;
}
}