LeetCode 第十九题 删除链表的倒数第N个节点
给定一个链表,删除链表的倒数第 n 个节点并返回头结点。
例如,
给定一个链表: 1->2->3->4->5, 并且 n = 2.当删除了倒数第二个节点后链表变成了 1->2->3->5.
说明:
给的 n 始终是有效的。
尝试一次遍历实现。
在这里我们参考了网址的解题算法。
方法一
需要注意的是,删除倒数第N个节点,其实就是删除第(L-n+1)
个节点,这里L表示整个链表的长度,我们可以首先遍历一遍链表,计算出链表的长度,接着根据L-n+1
找到该节点,做删除操作。
Java
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 -= n;
first = dummy;/// 确保了可以删除头节点的操作
while (length > 0) {
length--;
first = first.next;
}
first.next = first.next.next;
return dummy.next;
}
Python
class Solution(object):
def removeNthFromEnd(self, head, n):
dummy = ListNode(0)
dummy.next = head
length = 0
first = head
while (first):
length = length + 1
first = first.next
length = length - n
first = dummy
while (length > 0):
length = length - 1
first = first.next
will_delete = first.next
first.next = will_delete.next
del (will_delete)
return dummy.next
C++
ListNode* removeNthFromEnd(ListNode* head, int n)
{
ListNode dummy = ListNode(0);
dummy.next = head;
int length = 0;
ListNode* first = head;
while(first!=NULL)
{
length++;
first = first->next;
}
length -= n;
first = &dummy;
while(length>0)
{
length--;
first = first->next;
}
ListNode *will_delete = first->next;
first->next = will_delete->next;
delete(will_delete);
return dummy.next;
}
方法二
我们可以使用两个指针first和second,两个指针在初始状态时,都指向头节点,接着移动first指针,使其向后移动n个节点,这样first和second指针之间就间隔了n个节点,接着同时移动first和second指针(类似于平移的操作),直到first指针指向了尾节点,此时,second指针刚好指向了倒数第N个节点,将其删除。该算法十分巧妙,很喜欢。
Java
public ListNode removeNthFromEnd_2(ListNode head, int n) {
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode first = dummy;
ListNode second = dummy;
for (int i = 0; i <= n; i++) {
first = first.next;
}
while (first != null) {
first = first.next;
second = second.next;
}
second.next = second.next.next;
return dummy.next;
}
Python
def removeNthFromEnd_2(self, head, n):
dummy = ListNode(0)
dummy.next = head
first = dummy
second = dummy
for i in range(n + 1):
first = first.next
while (first):
first = first.next
second = second.next
will_delete = second.next
second.next = will_delete.next
del (will_delete)
return dummy.next
C++
ListNode* removeNthFromEnd_2(ListNode* head, int n)
{
ListNode dummy(0);
dummy.next=head;
ListNode* first=&dummy;
ListNode* second=&dummy;
for(int i=0;i<=n;i++)
{
first=first->next;
}
while(first!=NULL)
{
first=first->next;
second=second->next;
}
ListNode* will_delete = second->next;
second->next=will_delete->next;
delete(will_delete);
return dummy.next;
}