LeetCode19. 删除链表的倒数第 N 个结点【双指针】

本文介绍了LeetCode第19题的解决方案,包括两种思路:一是先计算链表长度再删除,二是使用双指针一次遍历完成。两种方法都涉及哨兵节点的使用,以简化边界条件处理。第一种方法需要两次遍历,而第二种方法通过双指针同步移动,仅需一次遍历,更高效。
摘要由CSDN通过智能技术生成

LeetCode19. 删除链表的倒数第 N 个结点

1.题目

在这里插入图片描述

2.思路

1.我自己的思路很简单粗暴,就是:
(1)求出链表长度(2)通过计算把倒数换为正数(3)删除结点
注意特判头结点!!使用哨兵结点方便处理头结点!!
2.简化版——利用双指针,仅需一趟扫描
下面分别实现。

3.代码实现

(1) 倒序转正序
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
   	    int size = 0;//链表长度
		ListNode* dummyHead = new ListNode(-1,head);//哨兵结点
		ListNode* p = dummyHead;
		
		while(p->next!= NULL)//第一次遍历:统计链表长度 
		{
			p = p->next;
			size++;	//链表长度 
		} 
		
		int a = size-n+1;//待删除的结点正序所在位置 从1开始!! 
		if(a == 1)//特判头结点
		{
			ListNode*q = head;
			dummyHead->next = head->next;
			head = head->next;//连接节点
			delete q;
            delete dummyHead;
			return head;
		}
		else//其他情况
		{
			ListNode *q = dummyHead;
			//从哨兵结点出发 只需要走 待删除结点的所在正序-1 步即可
			int cnt = size-n;
			while(cnt--)//第二次遍历
				q = q->next;
			ListNode *m = q->next;
			q->next = m->next;//连接节点
			delete m;
            delete dummyHead;
			return head;
		}
    }
};

注意事项

1.注意题目条件:n一定在size范围内
2.一个小总结,感觉自己每次在这里都会思考一下,有点浪费时间:
统计链表长度,如果从哨头结点出发要用

while(p->next!= NULL)
从头结点出发则是
while(p != NULL)

(2) 双指针

最重要的就是省去了求链表长度的步骤!!也不需要特判头结点!!
实现点:1.哨兵结点 2.双指针
思路见注释:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
		ListNode* dummyHead = new ListNode(-1,head) ;
		ListNode* fast = dummyHead;//快指针
		ListNode* slow = dummyHead;//慢指针
		int a = n+1;
		//1.快指针先走n+1步——为了使后期同步动时slow指向待删除结点的前一个,方便操作
		while(a--)
		fast = fast->next;//向后移n+1步
	
	   //2.快慢指针同步动,
		while(fast!=NULL)
		{
			slow = slow->next;
			fast = fast->next;
		} //此时slow指向待删除结点的前一个结点 
		
		//3.删除操作
		ListNode*p = slow->next;
		slow->next = p->next;
		delete p;
		return dummyHead->next; //注意这里!
    }
};

1.特别要注意的是最后一句
return dummyHead->next;

因为原来的头结点head可能已经被删去,新的头结点就是dummyHead->next。
2.n的值一定合理,所以不需要考虑太多!不会有指空的情况!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值