Given a linked list, remove the nth node from the end of list and return its head.
For example,
Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Try to do this in one pass.
思路一:删除倒数第n个节点,等价于删除链表的(L-n+1)个节点,L是整个链表的长度。
1、遍历链表,记录长度;
2、找到L-n+1的节点,让其前一个节点指向其后一个节点。
小技巧:对链表进行操作时,先新建一个dummy节点指向表头以便处理一些边界情况,如删除表头。
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;
}
思路二:使用两个指针分别指向表头和伪表头,指向表头的指针先走n歩后,另一个指针再走,当先走的指针到达链表末尾时,后走的指针正好指向的是待删除的指针的前一个指针。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* fast=head;
ListNode* dummy=new ListNode(-1);
dummy->next=head;
for(int i=0;i<n;++i)
{
fast=fast->next;
}
ListNode* slow=dummy;
while(fast!=nullptr)
{
fast=fast->next;
slow=slow->next;
}
slow->next=slow->next->next;
return dummy->next;
}
};