LEETCODE(力扣) 19. 删除链表的倒数第 N 个结点
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
示例 1:
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
示例 2:
输入:head = [1], n = 1
输出:[]
示例 3:
输入:head = [1,2], n = 1
输出:[1]
提示:
链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz
自解

(本来空间击败30,多提交两次就96.74了,乐)
第一时间想到了反转链表删除对应节点后再反转回去
考虑实用的话应该把删去的节点空间回收
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//反转链表再反回去
struct ListNode* reverse_list(struct ListNode*head)//反转链表
{
struct ListNode *last=NULL,*next=NULL;
while(head!=NULL)
{
next=head->next;
head->next=last;
last=head;
head=next;
}
return last;
}
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode *temp=NULL,*head1=NULL;
head=reverse_list(head);//反转
head1=head;//记录反转后的头节点
if(n<=1)//如果删除反转后的首结点
{
head=reverse_list(head->next);//直接将头节点之后节点反转回去,返回反转后的链表
return head;
}
n--;//遍历到删除的节点前面那个
while(--n)head=head->next;
head->next=head->next->next;//去掉要删掉的节点(实际要注意回收内存)
head1=reverse_list(head1);//链表反转后返回
return head1;
}
力扣解
三个解答里我认为双指针最优美
使用两个指针,快指针比慢指针快n,当快指针到NULL时,慢指针就在第n个节点
当然这样不太好直接删除该节点,因此可以用一个dummy节点,让慢指针再滞后一个节点,这样快指针指向NULL时慢指针就是需要删除节点的前一个结点。
struct ListNode* removeNthFromEnd(struct ListNode* head, int n) {
struct ListNode* dummy = malloc(sizeof(struct ListNode));
dummy->val = 0, dummy->next = head;
struct ListNode* first = head;
struct ListNode* second = dummy;
for (int i = 0; i < n; ++i) {
first = first->next;
}
while (first) {
first = first->next;
second = second->next;
}
second->next = second->next->next;
struct ListNode* ans = dummy->next;
free(dummy);
return ans;
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/solutions/450350/shan-chu-lian-biao-de-dao-shu-di-nge-jie-dian-b-61/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

浙公网安备 33010602011771号