链表 19.删除链表倒数第N个节点
题目
给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
示例
给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:给定的 n 保证是有效的。
分析
这道题的关键点就在链表的长度不知道,所以链表的长度尤为重要,最简单的方法就是,先遍历一遍链表,知道了长度之后再设定计数变量去遍历,就可以找到要删除的节点。
但仔细想想,没有办法只遍历一次了吗?当然可以,我们借鉴之前做过的链表中间节点的经验,可以这样设定一个指针先出发,再设一个指针慢出发,慢多少,就慢n+1拍,这样快指针结束遍历,慢指针此时就在倒数第n个节点的前一个节点,这样就可以将其残忍地删除。可一切都没有结束,如果n为表长的时候,快指针遍历完毕了,慢指针还在第一个节点,怎么办?此时要删除的就是第一个节点,把第一个节点的下一个节点返回就行了。
代码实现
/**
*C语言
*/
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* removeNthFromEnd(struct ListNode* head, int n){ struct ListNode *front = head; struct ListNode *rear = head; //遍历链表 while( front != NULL ) { //计数结束的条件 if( n < 0 ) { rear = rear->next; } n--; front = front->next; } //当n是表长的情况下,返回头结点的下一个即可。 if( n==0 ) { return head->next; } struct ListNode *temp = rear->next; rear->next = rear->next->next; free(temp); return head; }
纸上得来终觉浅,绝知此事要躬行