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.
当我们要删除链表中的某个结点时,需要找到要删除的结点的前驱结点pre,然后让pre指向要删除结点的下一个节点。
当删除倒数第n个结点时,pre与链表尾结点的距离恰好为n。
采用快慢指针法找到pre结点(代码中的slow),然后执行删除操作。
/**
* 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) {
if(head == NULL) return NULL;
//首先要找到倒数第n个节点
ListNode *fast = head;//先走的结点
ListNode *slow = head;
ListNode *pre = head;
while( n > 0 && fast){//fast走n步,slow才开始走,要删除的是fast走到链表末尾,slow的下一个节点
n --;//注意此处n--不能放在while里,因为如果放在while里,只有并列的两个条件都为真,才会执行--
fast = fast -> next;
}
if(n > 0)//不存在倒数第n个结点
return NULL;
if(n == 0){//fast指向最后一个节点时,slow指向的为要删除结点的前一个节点
ListNode *del = NULL;
if(!fast) {
del = head;
head = head -> next;
delete del;
del = NULL;
return head;//不能为return NULL。此处为要删除的结点恰好为首结点的情况
}
while( fast -> next){
fast = fast -> next;
slow = slow -> next;
}
del = slow -> next;
slow -> next = slow -> next -> next;
delete del;
del = NULL;
return head;
}
}
};