给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例:
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:
给定的 n 保证是有效的。
进阶:你能尝试使用一趟扫描实现吗?
解析:
首先需要考虑的是找到倒数第n个节点。指针q先确定倒数第N个节点的位置,它先走n步。再利用两个指针同时跑(p指针从头节点开始),当q指针跑完指向NULL时,此时p指针的位置就是待删节点的位置。为了删除待删节点,它必须有前驱指针,在遍历中记录就可以。ps:当q初始位置找到后为NULL时说明,n等于链表节点数,删除倒数第n个就是删除第一个节点。
C代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
if( head == NULL) return head;//非空判断
struct ListNode *p=NULL;
struct ListNode *t=NULL;
struct ListNode *q=head->next;
//q向前走n-1步
for(int i=0;i<n-1;i++){
q=q->next;
}
//对q进行非空判断
if(q==NULL){
t=head->next;
free(head);
return t;
}
//利用for死循环找到p的位置,
for(p=head; q!=NULL ;t=p,p=p->next,q=q->next);
t->next=p->next;
free(p);
return head;
}