题目描述
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:给定的 n 保证是有效的。进阶:你能尝试使用一趟扫描实现吗?
解题思路
方法一:双程
删除倒数第n个节点,也就是删除这个链表的第(L-n+1)个节点,L为链表的长度;如果知道L的值,这个问题就很容易解决了;
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head; //指向链表的头节点
int length = 0; //记录链表的长度
ListNode first = head;
//计算链表的长度
while (first != null) {
length++;
first = first.next;
}
length = length - n; //*
first = dummy;
//找到倒数第n+1个节点
while (length > 0) {
length--;
first = first.next;
}
first.next = first.next.next;
return dummy.next;
}
时间复杂度为O(L),空间复杂度为O(1);方法二:单程
1.创建两个指针;
2.让两个指针之间间隔n-1个节点
3.两个指针一起往后面走,当有个指针走到最后那个节点时,前面那个指针就走到了倒数第n+1个节点了;
public ListNode removeNthFromEnd2(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
//定义两个指针
ListNode first = dummy;
ListNode second = dummy;
// 让两个指针距离n个节点
for (int i = 1; i <= n + 1; i++) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
时间复杂度为O(L),空间复杂度为O(1);