给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
思路一:两遍遍历链表,第一遍确定链表长度i,第二遍找到第i-n-1个节点,删除它后面的节点。需要注意的是删除头节点的情况。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* h = head;
struct ListNode* s;
int i = 0,j;
while((h = h->next) != NULL)
i++;
h = head;
if(n == (i+1)){ //删除头节点的情况
head = head->next;
free(h);
return head;
}
for(j=0;j<i-n;j++){
h = h->next;
}
s = h->next;
h->next = h->next->next;
free(s);
return head;
}
思路二:用两个指针first,second指向头节点,先将first移动n次,此后first和second保持间距n移动,直到first->next为NULL,删除second之后的一个节点即可。同时也要考虑删除头节点的情况。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* first = head;
struct ListNode* second = head;
struct ListNode* temp;
int i = 0;
for(;i<n;i++){
first = first->next;
}
if(first == NULL){
head = head->next;
free(second);
return head;
}
while(first->next!=NULL){
first = first->next;
second = second->next;
}
temp = second->next;
second->next = second->next->next;
free(temp);
return head;
}