力扣每日一题:删除链表的倒数第N个节点
题目链接
思路有两个:
- 遍历一遍链表得到整个链表长度L,再遍历一次到L-n-1的地方进行删除节点
- 用快慢指针,相隔距离n
实现过程: - 刚开始用的是在原链表内进行操作,加上一些特殊情况,例如只有一个节点和删除的是第一个位置时。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode tmp = head;
ListNode mark = head;
int cnt = 0;
while (head != null) {
if (cnt > n)
mark = mark.next;
cnt++;
head = head.next;
}
if (cnt <= 1)//只有一个元素或为空
return null;
if (cnt == n)
return tmp.next;
mark.next = mark.next.next;
return tmp;
}
}
- 通过查看题解,回忆起一种经常在链表中使用的技巧——设置一个哑巴节点dummy,于是不用额外判断边界条件。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0, head);//哑巴节点
ListNode begin = dummy, end = head;
int cnt = 0;
while (end != null) {
cnt++;
if (cnt > n)
begin = begin.next;
end = end.next;
}
begin.next = begin.next.next;
return dummy.next;
}
}