今日学习的文章链接和视频链接
leetcode题目地址:19.删除链表的倒数第N个节点
代码随想录题解地址:代码随想录
题目简介
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
进阶:你能尝试使用一趟扫描实现吗?
看到题目的第一想法(可以贴代码)
1. 暴力解法:遍历得出链表长度len,for循环到(len-n),执行节点删除操作
2. 一趟扫描:遍历每一个node,设置一个boolean变量,每次往后for循环一个n长度,如果最后node.next = null,则true,删除当前node的下一个node。
3. 执行第2种方法时,还是需要一个空的头节点来统一操作,还有头部节点的删除(需要获取头节点的前一个节点来进行删除)。成功了!果然以后都要考虑空的头节点!
//使用dummy head的一趟扫描法
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
boolean check = false;
ListNode temp = dummy;
while (temp != null && check == false){
ListNode temp2 = temp;
for (int i = 0; i <= n; i++){
if (temp2.next == null) {
check = true;
break;
} else {
temp2 = temp2.next;
}
}
if (check) { break; }
temp = temp.next;
}
temp.next = temp.next.next;
return dummy.next;
}
实现过程中遇到哪些困难
1. 老是忘记使用空的头节点(dummy head),导致每次涉及头节点的删除操作时,难以处理。
看完代码随想录之后的想法
【解题思路】快指针+慢指针,快指针比慢指针快n个节点。
【想法】
1. 其实和我的for循环思路是一样的,但是时间复杂度会低很多!!需要熟练掌握双指针思路,并积极应用。
2. 单指针情况下,执行任何关于链表的操作的时候,都需要遍历到被操作节点的上一个节点,才能定位到被操作的节点处。
看完视频自己写的ACC:
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode slow = dummy;
ListNode fast = dummy;
for (int i = 0; i <= n; i++){
fast = fast.next;
}
while (fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummy.next;
}
学习时长
9:05 ~ 9:42 解题成功
9:42 ~ 9:52 看视频题解、写博客
今日收获
1. 代码格式:
public ListNode removeNthFromEnd(ListNode head, int n){
ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
ListNode fastIndex = dummyNode;
ListNode slowIndex = dummyNode;
// 只要快慢指针相差 n 个结点即可
for (int i = 0; i <= n ; i++){
fastIndex = fastIndex.next;
}
while (fastIndex != null){
fastIndex = fastIndex.next;
slowIndex = slowIndex.next;
}
//此时 slowIndex 的位置就是待删除元素的前一个位置。
//具体情况可自己画一个链表长度为 3 的图来模拟代码来理解
slowIndex.next = slowIndex.next.next;
return dummyNode.next;
}
左“ { ”的左边不留空格;