题目
给定一个链表,删除链表中倒数第n个节点,返回链表的头节点。
注意事项
链表中的节点个数大于等于n
样例
给出链表1->2->3->4->5->null和 n = 2.
删除倒数第二个节点之后,这个链表将变成1->2->3->5->null.
//Definition for ListNode.
public class ListNode {
int val;//数据
ListNode next;//指针
ListNode(int val) {
this.val = val;
this.next = null;
}
}
常规遍历法
先遍历一遍单链表,计算出单链表的长度,然后从单链表头部删除指定的节点。
ListNode removeNthFromEnd(ListNode head, int n) {
// write your code here
if (head == null) {
return null;
}
int len = 0;
ListNode cur = head;
//计算链表的长度
while (cur != null) {
len++;
cur = cur.next;
}
//计算正向的位置
int where = len - n + 1;
if (where == 1) {
return head.next;
}
cur = head;
int i = 0;
while (cur != null) {
i++;
if (i == where - 1) {
cur.next = cur.next.next;
}
cur = cur.next;
}
return head;
}
快慢指针法
使用快慢指针。快指针比慢指针提前n个单元。当快指针到达单链表尾部时,慢指针指向待删除节点的前节点。
ListNode removeNthFromEnd(ListNode head, int n) {
if (head == null)
return null;
ListNode fast = head;//快指针
ListNode slow = head;//慢指针
//快指针提前移动n次
for (int i = 0; i < n; i++) {
fast = fast.next;
}
//删除的是链表头部
if (fast == null) {
return head.next;
}
//同时移动快慢指针,直到快指针到链表末尾
//说明慢指针在要删除的位置上
while (fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
}
}