链表5:删除链表的倒数第 N 个结点

本文介绍了如何解决链表中删除倒数第n个节点的问题,采用双指针法,通过设置虚拟头结点简化边界条件。首先让快指针移动n+1步,然后同时移动两个指针,直到快指针到达末尾,此时慢指针指向待删除节点的前一个节点,然后删除即可。此外,还提供了一种统计节点数后再定位删除节点的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要是我自己刷题的一些记录过程。如果有错可以指出哦,大家一起进步。
转载代码随想录
原文链接:
代码随想录

题目:

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例:

在这里插入图片描述

提示:

链表中结点的数目为 sz
1 <= sz <= 30
0 <= Node.val <= 100
1 <= n <= sz

进阶:你能尝试使用一趟扫描实现吗?

思路:

双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。

思路是这样的,但要注意一些细节。

分为如下几步:

首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑。
定义fast指针和slow指针,初始值为虚拟头结点,如图:
在这里插入图片描述
fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作),如图:
在这里插入图片描述
fast和slow同时移动,直到fast指向末尾,如题:
在这里插入图片描述
删除slow指向的下一个节点,如图:
在这里插入图片描述

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
		ListNode* dummyHead = new ListNode(0,head);
		ListNode* slow = dummyHead;
		ListNode* fast = dummyHead;
		while(n-- && fast!= nullptr){
			fast =  fast->next;
		}
		fast =  fast->next;// fast再提前走一步,因为需要让slow指向删除节点的上一个节点
		while(fast !=nullptr){
			fast=fast->next;
			slow=slow->next;
		}
		slow->next = slow->next->next;
		// ListNode *tmp = slow->next;  C++释放内存的逻辑
        // slow->next = tmp->next;
        // delete tmp;
        return dummyHead->next;
    }
};

自己的代码

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        		if (!head)
			return head;
		//统计节点个数
		ListNode* cur = head;
		int size = 0;
		while (cur) {
			++size;
			cur = cur->next;
		}
		if (n == size) {
			return head->next;
		}

		ListNode* pre = head;
		int num = size - n;
		while (--num) {
			pre = pre->next;
		}

		//ListNode* temp = pre->next;
		pre->next = pre->next->next;
		//delete temp;
		return head;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值